mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-06 14:42:11 +00:00
fix: conditionally disable reqs to the server in prod (#456)
* fix: conditionally disable reqs to the server in prod * cr
This commit is contained in:
parent
9a4b63b798
commit
05bc1b3559
1 changed files with 188 additions and 184 deletions
|
|
@ -1,24 +1,24 @@
|
||||||
import { Auth, HTTPException } from "@langchain/langgraph-sdk/auth";
|
import { Auth, HTTPException } from "@langchain/langgraph-sdk/auth";
|
||||||
// import {
|
import {
|
||||||
// verifyGithubUser,
|
verifyGithubUser,
|
||||||
// GithubUser,
|
GithubUser,
|
||||||
// verifyGithubUserId,
|
verifyGithubUserId,
|
||||||
// } from "@open-swe/shared/github/verify-user";
|
} from "@open-swe/shared/github/verify-user";
|
||||||
// import {
|
import {
|
||||||
// API_KEY_REQUIRED_MESSAGE,
|
API_KEY_REQUIRED_MESSAGE,
|
||||||
// GITHUB_INSTALLATION_NAME,
|
GITHUB_INSTALLATION_NAME,
|
||||||
// GITHUB_INSTALLATION_TOKEN_COOKIE,
|
GITHUB_INSTALLATION_TOKEN_COOKIE,
|
||||||
// GITHUB_TOKEN_COOKIE,
|
GITHUB_TOKEN_COOKIE,
|
||||||
// GITHUB_USER_ID_HEADER,
|
GITHUB_USER_ID_HEADER,
|
||||||
// GITHUB_USER_LOGIN_HEADER,
|
GITHUB_USER_LOGIN_HEADER,
|
||||||
// } from "@open-swe/shared/constants";
|
} from "@open-swe/shared/constants";
|
||||||
// import { decryptSecret } from "@open-swe/shared/crypto";
|
import { decryptSecret } from "@open-swe/shared/crypto";
|
||||||
// import { verifyGitHubWebhookOrThrow } from "./github.js";
|
import { verifyGitHubWebhookOrThrow } from "./github.js";
|
||||||
import { createWithOwnerMetadata, createOwnerFilter } from "./utils.js";
|
import { createWithOwnerMetadata, createOwnerFilter } from "./utils.js";
|
||||||
// import { LANGGRAPH_USER_PERMISSIONS } from "../constants.js";
|
import { LANGGRAPH_USER_PERMISSIONS } from "../constants.js";
|
||||||
// import { getGitHubPatFromRequest } from "../utils/github-pat.js";
|
import { getGitHubPatFromRequest } from "../utils/github-pat.js";
|
||||||
// import { isAllowedUser } from "../utils/github/allowed-users.js";
|
import { isAllowedUser } from "../utils/github/allowed-users.js";
|
||||||
// import { validate } from "uuid";
|
import { validate } from "uuid";
|
||||||
|
|
||||||
// TODO: Export from LangGraph SDK
|
// TODO: Export from LangGraph SDK
|
||||||
export interface BaseAuthReturn {
|
export interface BaseAuthReturn {
|
||||||
|
|
@ -34,189 +34,193 @@ interface AuthenticateReturn extends BaseAuthReturn {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// function apiKeysInRequestBody(
|
function apiKeysInRequestBody(
|
||||||
// bodyStr: string | Record<string, unknown>,
|
bodyStr: string | Record<string, unknown>,
|
||||||
// ): boolean {
|
): boolean {
|
||||||
// try {
|
try {
|
||||||
// const body = typeof bodyStr === "string" ? JSON.parse(bodyStr) : bodyStr;
|
const body = typeof bodyStr === "string" ? JSON.parse(bodyStr) : bodyStr;
|
||||||
// if (
|
if (
|
||||||
// body.config?.configurable &&
|
body.config?.configurable &&
|
||||||
// ("anthropicApiKey" in body.config.configurable.apiKeys ||
|
("anthropicApiKey" in body.config.configurable.apiKeys ||
|
||||||
// "openaiApiKey" in body.config.configurable.apiKeys ||
|
"openaiApiKey" in body.config.configurable.apiKeys ||
|
||||||
// "googleApiKey" in body.config.configurable.apiKeys)
|
"googleApiKey" in body.config.configurable.apiKeys)
|
||||||
// ) {
|
) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
// } catch {
|
} catch {
|
||||||
// // no-op
|
// no-op
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// function isRunReq(reqUrl: string): boolean {
|
function isRunReq(reqUrl: string): boolean {
|
||||||
// try {
|
try {
|
||||||
// const url = new URL(reqUrl);
|
const url = new URL(reqUrl);
|
||||||
// const pathnameParts = url.pathname.split("/");
|
const pathnameParts = url.pathname.split("/");
|
||||||
// const isCreateAndWait = !!(
|
const isCreateAndWait = !!(
|
||||||
// pathnameParts[1] === "threads" &&
|
pathnameParts[1] === "threads" &&
|
||||||
// validate(pathnameParts[2]) &&
|
validate(pathnameParts[2]) &&
|
||||||
// pathnameParts[3] === "runs" &&
|
pathnameParts[3] === "runs" &&
|
||||||
// pathnameParts[4] === "wait" &&
|
pathnameParts[4] === "wait" &&
|
||||||
// pathnameParts.length === 5
|
pathnameParts.length === 5
|
||||||
// );
|
);
|
||||||
// const isCreateBackground = !!(
|
const isCreateBackground = !!(
|
||||||
// pathnameParts[1] === "threads" &&
|
pathnameParts[1] === "threads" &&
|
||||||
// validate(pathnameParts[2]) &&
|
validate(pathnameParts[2]) &&
|
||||||
// pathnameParts[3] === "runs" &&
|
pathnameParts[3] === "runs" &&
|
||||||
// pathnameParts.length === 4
|
pathnameParts.length === 4
|
||||||
// );
|
);
|
||||||
// const isCreateStream = !!(
|
const isCreateStream = !!(
|
||||||
// pathnameParts[1] === "threads" &&
|
pathnameParts[1] === "threads" &&
|
||||||
// validate(pathnameParts[2]) &&
|
validate(pathnameParts[2]) &&
|
||||||
// pathnameParts[3] === "runs" &&
|
pathnameParts[3] === "runs" &&
|
||||||
// pathnameParts[4] === "stream" &&
|
pathnameParts[4] === "stream" &&
|
||||||
// pathnameParts.length === 5
|
pathnameParts.length === 5
|
||||||
// );
|
);
|
||||||
|
|
||||||
// return !!isCreateAndWait || !!isCreateBackground || !!isCreateStream;
|
return !!isCreateAndWait || !!isCreateBackground || !!isCreateStream;
|
||||||
// } catch {
|
} catch {
|
||||||
// // no-op
|
// no-op
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
export const auth = new Auth()
|
export const auth = new Auth()
|
||||||
.authenticate<AuthenticateReturn>(async (_request: Request) => {
|
.authenticate<AuthenticateReturn>(async (request: Request) => {
|
||||||
return new HTTPException(504, {
|
const isProdEnv = process.env.NODE_ENV === "production";
|
||||||
message: "Open SWE temporarily disabled.",
|
// Disable all requests to the server in prod for now.
|
||||||
}) as any;
|
if (!isProdEnv) {
|
||||||
|
return new HTTPException(504, {
|
||||||
|
message: "Open SWE temporarily disabled.",
|
||||||
|
}) as any;
|
||||||
|
}
|
||||||
|
|
||||||
// if (request.method === "OPTIONS") {
|
if (request.method === "OPTIONS") {
|
||||||
// return {
|
return {
|
||||||
// identity: "anonymous",
|
identity: "anonymous",
|
||||||
// permissions: [],
|
permissions: [],
|
||||||
// is_authenticated: false,
|
is_authenticated: false,
|
||||||
// display_name: "CORS Preflight",
|
display_name: "CORS Preflight",
|
||||||
// metadata: {
|
metadata: {
|
||||||
// installation_name: "n/a",
|
installation_name: "n/a",
|
||||||
// },
|
},
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const isProd = process.env.NODE_ENV === "production";
|
const isProd = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
// const ghSecretHashHeader = request.headers.get("X-Hub-Signature-256");
|
const ghSecretHashHeader = request.headers.get("X-Hub-Signature-256");
|
||||||
// if (ghSecretHashHeader) {
|
if (ghSecretHashHeader) {
|
||||||
// // This will either return a valid user, or throw an error
|
// This will either return a valid user, or throw an error
|
||||||
// return await verifyGitHubWebhookOrThrow(request);
|
return await verifyGitHubWebhookOrThrow(request);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const encryptionKey = process.env.SECRETS_ENCRYPTION_KEY;
|
const encryptionKey = process.env.SECRETS_ENCRYPTION_KEY;
|
||||||
// if (!encryptionKey) {
|
if (!encryptionKey) {
|
||||||
// throw new Error("Missing SECRETS_ENCRYPTION_KEY environment variable.");
|
throw new Error("Missing SECRETS_ENCRYPTION_KEY environment variable.");
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Check for GitHub PAT authentication (simpler mode for evals, etc.)
|
// Check for GitHub PAT authentication (simpler mode for evals, etc.)
|
||||||
// const githubPat = getGitHubPatFromRequest(request, encryptionKey);
|
const githubPat = getGitHubPatFromRequest(request, encryptionKey);
|
||||||
// if (githubPat && !isProd) {
|
if (githubPat && !isProd) {
|
||||||
// const user = await verifyGithubUser(githubPat);
|
const user = await verifyGithubUser(githubPat);
|
||||||
// if (!user) {
|
if (!user) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: "Invalid GitHub PAT",
|
message: "Invalid GitHub PAT",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return {
|
return {
|
||||||
// identity: user.id.toString(),
|
identity: user.id.toString(),
|
||||||
// is_authenticated: true,
|
is_authenticated: true,
|
||||||
// display_name: user.login,
|
display_name: user.login,
|
||||||
// metadata: {
|
metadata: {
|
||||||
// installation_name: "pat-auth",
|
installation_name: "pat-auth",
|
||||||
// },
|
},
|
||||||
// permissions: LANGGRAPH_USER_PERMISSIONS,
|
permissions: LANGGRAPH_USER_PERMISSIONS,
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // GitHub App authentication mode (existing logic)
|
// GitHub App authentication mode (existing logic)
|
||||||
// const installationNameHeader = request.headers.get(
|
const installationNameHeader = request.headers.get(
|
||||||
// GITHUB_INSTALLATION_NAME,
|
GITHUB_INSTALLATION_NAME,
|
||||||
// );
|
);
|
||||||
// if (!installationNameHeader) {
|
if (!installationNameHeader) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: "GitHub installation name header missing",
|
message: "GitHub installation name header missing",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // We don't do anything with this token right now, but still confirm it
|
// We don't do anything with this token right now, but still confirm it
|
||||||
// // exists as it will cause issues later on if it's not present.
|
// exists as it will cause issues later on if it's not present.
|
||||||
// const encryptedInstallationToken = request.headers.get(
|
const encryptedInstallationToken = request.headers.get(
|
||||||
// GITHUB_INSTALLATION_TOKEN_COOKIE,
|
GITHUB_INSTALLATION_TOKEN_COOKIE,
|
||||||
// );
|
);
|
||||||
// if (!encryptedInstallationToken) {
|
if (!encryptedInstallationToken) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: "GitHub installation token header missing",
|
message: "GitHub installation token header missing",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const encryptedAccessToken = request.headers.get(GITHUB_TOKEN_COOKIE);
|
const encryptedAccessToken = request.headers.get(GITHUB_TOKEN_COOKIE);
|
||||||
// const decryptedAccessToken = encryptedAccessToken
|
const decryptedAccessToken = encryptedAccessToken
|
||||||
// ? decryptSecret(encryptedAccessToken, encryptionKey)
|
? decryptSecret(encryptedAccessToken, encryptionKey)
|
||||||
// : undefined;
|
: undefined;
|
||||||
// const decryptedInstallationToken = decryptSecret(
|
const decryptedInstallationToken = decryptSecret(
|
||||||
// encryptedInstallationToken,
|
encryptedInstallationToken,
|
||||||
// encryptionKey,
|
encryptionKey,
|
||||||
// );
|
);
|
||||||
|
|
||||||
// let user: GithubUser | undefined;
|
let user: GithubUser | undefined;
|
||||||
|
|
||||||
// if (!decryptedAccessToken) {
|
if (!decryptedAccessToken) {
|
||||||
// // If there isn't a user access token, check to see if the user info is in headers.
|
// If there isn't a user access token, check to see if the user info is in headers.
|
||||||
// // This would indicate a bot created the request.
|
// This would indicate a bot created the request.
|
||||||
// const userIdHeader = request.headers.get(GITHUB_USER_ID_HEADER);
|
const userIdHeader = request.headers.get(GITHUB_USER_ID_HEADER);
|
||||||
// const userLoginHeader = request.headers.get(GITHUB_USER_LOGIN_HEADER);
|
const userLoginHeader = request.headers.get(GITHUB_USER_LOGIN_HEADER);
|
||||||
// if (!userIdHeader || !userLoginHeader) {
|
if (!userIdHeader || !userLoginHeader) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: "Github-User-Id or Github-User-Login header missing",
|
message: "Github-User-Id or Github-User-Login header missing",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// user = await verifyGithubUserId(
|
user = await verifyGithubUserId(
|
||||||
// decryptedInstallationToken,
|
decryptedInstallationToken,
|
||||||
// Number(userIdHeader),
|
Number(userIdHeader),
|
||||||
// userLoginHeader,
|
userLoginHeader,
|
||||||
// );
|
);
|
||||||
// } else {
|
} else {
|
||||||
// // Ensure we decrypt the token before passing to the verification function.
|
// Ensure we decrypt the token before passing to the verification function.
|
||||||
// user = await verifyGithubUser(decryptedAccessToken);
|
user = await verifyGithubUser(decryptedAccessToken);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (!user) {
|
if (!user) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: "User not found",
|
message: "User not found",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const reqCopy = request.clone();
|
const reqCopy = request.clone();
|
||||||
// const reqBody = await reqCopy.text();
|
const reqBody = await reqCopy.text();
|
||||||
// if (!isAllowedUser(user.login)) {
|
if (!isAllowedUser(user.login)) {
|
||||||
// if (isRunReq(request.url)) {
|
if (isRunReq(request.url)) {
|
||||||
// if (!apiKeysInRequestBody(reqBody)) {
|
if (!apiKeysInRequestBody(reqBody)) {
|
||||||
// throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
// message: API_KEY_REQUIRED_MESSAGE,
|
message: API_KEY_REQUIRED_MESSAGE,
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return {
|
return {
|
||||||
// identity: user.id.toString(),
|
identity: user.id.toString(),
|
||||||
// is_authenticated: true,
|
is_authenticated: true,
|
||||||
// display_name: user.login,
|
display_name: user.login,
|
||||||
// metadata: {
|
metadata: {
|
||||||
// installation_name: installationNameHeader,
|
installation_name: installationNameHeader,
|
||||||
// },
|
},
|
||||||
// permissions: LANGGRAPH_USER_PERMISSIONS,
|
permissions: LANGGRAPH_USER_PERMISSIONS,
|
||||||
// };
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
// THREADS: create operations with metadata
|
// THREADS: create operations with metadata
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue