mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-14 00:09:55 +02:00
add missing routes to integration api
This commit is contained in:
@@ -1456,6 +1456,13 @@
|
|||||||
"actionGetAiModel": "Get AI Model",
|
"actionGetAiModel": "Get AI Model",
|
||||||
"actionListAiModels": "List AI Models",
|
"actionListAiModels": "List AI Models",
|
||||||
"actionUpdateAiModel": "Update AI Model",
|
"actionUpdateAiModel": "Update AI Model",
|
||||||
|
"actionCreateAiBudget": "Create AI Budget",
|
||||||
|
"actionDeleteAiBudget": "Delete AI Budget",
|
||||||
|
"actionGetAiBudget": "Get AI Budget",
|
||||||
|
"actionListAiBudgets": "List AI Budgets",
|
||||||
|
"actionUpdateAiBudget": "Update AI Budget",
|
||||||
|
"actionListResourceAiModels": "List Resource AI Models",
|
||||||
|
"actionSetResourceAiModels": "Set Resource AI Models",
|
||||||
"actionCreateVirtualApiKey": "Create Virtual API Key",
|
"actionCreateVirtualApiKey": "Create Virtual API Key",
|
||||||
"actionDeleteVirtualApiKey": "Delete Virtual API Key",
|
"actionDeleteVirtualApiKey": "Delete Virtual API Key",
|
||||||
"actionGetVirtualApiKey": "Get Virtual API Key",
|
"actionGetVirtualApiKey": "Get Virtual API Key",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export * from "./verifyApiKeyIdpAccess";
|
|||||||
export * from "./verifyApiKeyDomainAccess";
|
export * from "./verifyApiKeyDomainAccess";
|
||||||
export * from "./verifyApiKeyAiProviderAccess";
|
export * from "./verifyApiKeyAiProviderAccess";
|
||||||
export * from "./verifyApiKeyAiModelAccess";
|
export * from "./verifyApiKeyAiModelAccess";
|
||||||
|
export * from "./verifyApiKeyAiBudgetAccess";
|
||||||
export * from "./verifyApiKeyResourcePolicyAccess";
|
export * from "./verifyApiKeyResourcePolicyAccess";
|
||||||
export * from "./verifyApiKeySiteProvisioningKeyAccess";
|
export * from "./verifyApiKeySiteProvisioningKeyAccess";
|
||||||
export * from "./verifyVirtualApiKeyAccess";
|
export * from "./verifyVirtualApiKeyAccess";
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { Request, Response, NextFunction } from "express";
|
||||||
|
import { aiBudgets, apiKeyOrg, db } from "@server/db";
|
||||||
|
import { and, eq } from "drizzle-orm";
|
||||||
|
import createHttpError from "http-errors";
|
||||||
|
import HttpCode from "@server/types/HttpCode";
|
||||||
|
import { getFirstString } from "@server/lib/requestParams";
|
||||||
|
|
||||||
|
export async function verifyApiKeyAiBudgetAccess(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const apiKey = req.apiKey;
|
||||||
|
const budgetIdRaw = getFirstString(req.params.budgetId);
|
||||||
|
const budgetId = Number.parseInt(budgetIdRaw ?? "", 10);
|
||||||
|
|
||||||
|
if (!apiKey) {
|
||||||
|
return next(
|
||||||
|
createHttpError(HttpCode.UNAUTHORIZED, "Key not authenticated")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isNaN(budgetId)) {
|
||||||
|
return next(
|
||||||
|
createHttpError(HttpCode.BAD_REQUEST, "Invalid budget ID")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [budget] = await db
|
||||||
|
.select()
|
||||||
|
.from(aiBudgets)
|
||||||
|
.where(eq(aiBudgets.budgetId, budgetId))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (!budget) {
|
||||||
|
return next(
|
||||||
|
createHttpError(
|
||||||
|
HttpCode.NOT_FOUND,
|
||||||
|
`AI budget with ID ${budgetId} not found`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiKey.isRoot) {
|
||||||
|
req.aiBudget = budget;
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const orgId = budget.orgId;
|
||||||
|
|
||||||
|
if (!req.apiKeyOrg || req.apiKeyOrg.orgId !== orgId) {
|
||||||
|
const apiKeyOrgRes = await db
|
||||||
|
.select()
|
||||||
|
.from(apiKeyOrg)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(apiKeyOrg.apiKeyId, apiKey.apiKeyId),
|
||||||
|
eq(apiKeyOrg.orgId, orgId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.limit(1);
|
||||||
|
req.apiKeyOrg = apiKeyOrgRes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.apiKeyOrg) {
|
||||||
|
return next(
|
||||||
|
createHttpError(
|
||||||
|
HttpCode.FORBIDDEN,
|
||||||
|
"Key does not have access to this organization"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.aiBudget = budget;
|
||||||
|
return next();
|
||||||
|
} catch (error) {
|
||||||
|
return next(
|
||||||
|
createHttpError(
|
||||||
|
HttpCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"Error verifying AI budget access"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import * as idp from "./idp";
|
|||||||
import * as logs from "./auditLogs";
|
import * as logs from "./auditLogs";
|
||||||
import * as siteResource from "./siteResource";
|
import * as siteResource from "./siteResource";
|
||||||
import * as aiProvider from "./aiProvider";
|
import * as aiProvider from "./aiProvider";
|
||||||
|
import * as aiBudget from "./aiBudget";
|
||||||
import * as virtualApiKey from "./virtualApiKey";
|
import * as virtualApiKey from "./virtualApiKey";
|
||||||
import {
|
import {
|
||||||
verifyApiKey,
|
verifyApiKey,
|
||||||
@@ -35,6 +36,7 @@ import {
|
|||||||
verifyApiKeyResourcePolicyAccess,
|
verifyApiKeyResourcePolicyAccess,
|
||||||
verifyApiKeyAiProviderAccess,
|
verifyApiKeyAiProviderAccess,
|
||||||
verifyApiKeyAiModelAccess,
|
verifyApiKeyAiModelAccess,
|
||||||
|
verifyApiKeyAiBudgetAccess,
|
||||||
verifyApiKeyVirtualApiKeyAccess,
|
verifyApiKeyVirtualApiKeyAccess,
|
||||||
verifyUserHasAction
|
verifyUserHasAction
|
||||||
} from "@server/middlewares";
|
} from "@server/middlewares";
|
||||||
@@ -1670,6 +1672,20 @@ authenticated.get(
|
|||||||
aiProvider.listAiModels
|
aiProvider.listAiModels
|
||||||
);
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/ai-provider/:providerId/catalog-models",
|
||||||
|
verifyApiKeyAiProviderAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiModels),
|
||||||
|
aiProvider.listCatalogModels
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/org/:orgId/ai-catalog-models",
|
||||||
|
verifyApiKeyOrgAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiModels),
|
||||||
|
aiProvider.listCatalogModelsByType
|
||||||
|
);
|
||||||
|
|
||||||
authenticated.get(
|
authenticated.get(
|
||||||
"/ai-model/:modelId",
|
"/ai-model/:modelId",
|
||||||
verifyApiKeyAiModelAccess,
|
verifyApiKeyAiModelAccess,
|
||||||
@@ -1693,6 +1709,44 @@ authenticated.delete(
|
|||||||
aiProvider.deleteAiModel
|
aiProvider.deleteAiModel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
authenticated.put(
|
||||||
|
"/org/:orgId/ai-budget",
|
||||||
|
verifyApiKeyOrgAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.createAiBudget),
|
||||||
|
logActionAudit(ActionsEnum.createAiBudget),
|
||||||
|
aiBudget.createAiBudget
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/org/:orgId/ai-budgets",
|
||||||
|
verifyApiKeyOrgAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgets
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/ai-budget/:budgetId",
|
||||||
|
verifyApiKeyAiBudgetAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.getAiBudget),
|
||||||
|
aiBudget.getAiBudget
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.post(
|
||||||
|
"/ai-budget/:budgetId",
|
||||||
|
verifyApiKeyAiBudgetAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.updateAiBudget),
|
||||||
|
logActionAudit(ActionsEnum.updateAiBudget),
|
||||||
|
aiBudget.updateAiBudget
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.delete(
|
||||||
|
"/ai-budget/:budgetId",
|
||||||
|
verifyApiKeyAiBudgetAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.deleteAiBudget),
|
||||||
|
logActionAudit(ActionsEnum.deleteAiBudget),
|
||||||
|
aiBudget.deleteAiBudget
|
||||||
|
);
|
||||||
|
|
||||||
authenticated.put(
|
authenticated.put(
|
||||||
"/org/:orgId/virtual-api-key",
|
"/org/:orgId/virtual-api-key",
|
||||||
verifyApiKeyOrgAccess,
|
verifyApiKeyOrgAccess,
|
||||||
@@ -1730,3 +1784,51 @@ authenticated.delete(
|
|||||||
logActionAudit(ActionsEnum.deleteVirtualApiKey),
|
logActionAudit(ActionsEnum.deleteVirtualApiKey),
|
||||||
virtualApiKey.deleteVirtualApiKey
|
virtualApiKey.deleteVirtualApiKey
|
||||||
);
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/ai-provider/:providerId/ai-budgets",
|
||||||
|
verifyApiKeyAiProviderAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForProvider
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/ai-model/:modelId/ai-budgets",
|
||||||
|
verifyApiKeyAiModelAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForModel
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
[
|
||||||
|
"/resource/:resourceId/ai-budgets",
|
||||||
|
"/public-resource/:resourceId/ai-budgets"
|
||||||
|
],
|
||||||
|
verifyApiKeyResourceAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForResource
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
[
|
||||||
|
"/site-resource/:siteResourceId/ai-budgets",
|
||||||
|
"/private-resource/:siteResourceId/ai-budgets"
|
||||||
|
],
|
||||||
|
verifyApiKeySiteResourceAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForSiteResource
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/role/:roleId/ai-budgets",
|
||||||
|
verifyApiKeyRoleAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForRole
|
||||||
|
);
|
||||||
|
|
||||||
|
authenticated.get(
|
||||||
|
"/virtual-api-key/:virtualApiKeyId/ai-budgets",
|
||||||
|
verifyApiKeyVirtualApiKeyAccess,
|
||||||
|
verifyApiKeyHasAction(ActionsEnum.listAiBudgets),
|
||||||
|
aiBudget.listAiBudgetsForVirtualApiKey
|
||||||
|
);
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ function getActionsCategories(root: boolean) {
|
|||||||
[t("actionGetSiteResource")]: "getSiteResource",
|
[t("actionGetSiteResource")]: "getSiteResource",
|
||||||
[t("actionListSiteResources")]: "listSiteResources",
|
[t("actionListSiteResources")]: "listSiteResources",
|
||||||
[t("actionUpdateSiteResource")]: "updateSiteResource",
|
[t("actionUpdateSiteResource")]: "updateSiteResource",
|
||||||
|
[t("actionListResourceAiModels")]: "listResourceAiModels",
|
||||||
|
[t("actionSetResourceAiModels")]: "setResourceAiModels",
|
||||||
[t("actionCreateResourceSessionToken")]:
|
[t("actionCreateResourceSessionToken")]:
|
||||||
"createResourceSessionToken"
|
"createResourceSessionToken"
|
||||||
},
|
},
|
||||||
@@ -171,6 +173,14 @@ function getActionsCategories(root: boolean) {
|
|||||||
[t("actionUpdateAiModel")]: "updateAiModel"
|
[t("actionUpdateAiModel")]: "updateAiModel"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"AI Budget": {
|
||||||
|
[t("actionCreateAiBudget")]: "createAiBudget",
|
||||||
|
[t("actionDeleteAiBudget")]: "deleteAiBudget",
|
||||||
|
[t("actionGetAiBudget")]: "getAiBudget",
|
||||||
|
[t("actionListAiBudgets")]: "listAiBudgets",
|
||||||
|
[t("actionUpdateAiBudget")]: "updateAiBudget"
|
||||||
|
},
|
||||||
|
|
||||||
"Virtual API Key": {
|
"Virtual API Key": {
|
||||||
[t("actionCreateVirtualApiKey")]: "createVirtualApiKey",
|
[t("actionCreateVirtualApiKey")]: "createVirtualApiKey",
|
||||||
[t("actionDeleteVirtualApiKey")]: "deleteVirtualApiKey",
|
[t("actionDeleteVirtualApiKey")]: "deleteVirtualApiKey",
|
||||||
|
|||||||
Reference in New Issue
Block a user