refactor: use the verify_secret_key util for all api handlers (#2284)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::{Query, State},
|
||||
@@ -85,15 +86,7 @@ async fn extend_prompt(
|
||||
headers: HeaderMap,
|
||||
Json(payload): Json<ExtendPromptRequest>,
|
||||
) -> Result<Json<ExtendPromptResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let mut agent = state.agent.write().await;
|
||||
if let Some(ref mut agent) = *agent {
|
||||
@@ -110,15 +103,7 @@ async fn create_agent(
|
||||
headers: HeaderMap,
|
||||
Json(payload): Json<CreateAgentRequest>,
|
||||
) -> Result<Json<CreateAgentResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Set the environment variable for the model if provided
|
||||
if let Some(model) = &payload.model {
|
||||
@@ -187,14 +172,7 @@ async fn get_tools(
|
||||
headers: HeaderMap,
|
||||
Query(query): Query<GetToolsQuery>,
|
||||
) -> Result<Json<Vec<ToolInfo>>, StatusCode> {
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let config = Config::global();
|
||||
let goose_mode = config.get_param("GOOSE_MODE").unwrap_or("auto".to_string());
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::routes::utils::check_provider_configured;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
@@ -5,6 +6,7 @@ use axum::{
|
||||
routing::{delete, get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
|
||||
use goose::config::Config;
|
||||
use goose::config::{extensions::name_to_key, PermissionManager};
|
||||
use goose::config::{ExtensionConfigManager, ExtensionEntry};
|
||||
@@ -12,26 +14,13 @@ use goose::providers::base::ProviderMetadata;
|
||||
use goose::providers::providers as get_providers;
|
||||
use goose::{agents::ExtensionConfig, config::permission::PermissionLevel};
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use serde_yaml;
|
||||
use std::collections::HashMap;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
fn verify_secret_key(headers: &HeaderMap, state: &AppState) -> Result<StatusCode, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
Err(StatusCode::UNAUTHORIZED)
|
||||
} else {
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ExtensionResponse {
|
||||
pub extensions: Vec<ExtensionEntry>,
|
||||
@@ -431,8 +420,6 @@ pub async fn upsert_permissions(
|
||||
Ok(Json("Permissions updated successfully".to_string()))
|
||||
}
|
||||
|
||||
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
|
||||
use once_cell::sync::Lazy;
|
||||
pub static APP_STRATEGY: Lazy<AppStrategyArgs> = Lazy::new(|| AppStrategyArgs {
|
||||
top_level_domain: "Block".to_string(),
|
||||
author: "Block".to_string(),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::{Query, State},
|
||||
@@ -29,15 +30,7 @@ async fn store_config(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<ConfigRequest>,
|
||||
) -> Result<Json<ConfigResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let config = Config::global();
|
||||
let result = if request.is_secret {
|
||||
@@ -159,15 +152,7 @@ pub async fn get_config(
|
||||
headers: HeaderMap,
|
||||
Query(query): Query<GetConfigQuery>,
|
||||
) -> Result<Json<GetConfigResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Fetch the configuration value. Right now we don't allow get a secret.
|
||||
let config = Config::global();
|
||||
@@ -193,15 +178,7 @@ async fn delete_config(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<DeleteConfigRequest>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Attempt to delete the key
|
||||
let config = Config::global();
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::env;
|
||||
use std::path::Path;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::state::AppState;
|
||||
use axum::{extract::State, routing::post, Json, Router};
|
||||
use goose::agents::{extension::Envs, ExtensionConfig};
|
||||
@@ -82,6 +83,8 @@ async fn add_extension(
|
||||
headers: HeaderMap,
|
||||
raw: axum::extract::Json<serde_json::Value>,
|
||||
) -> Result<Json<ExtensionResponse>, StatusCode> {
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Log the raw request for debugging
|
||||
tracing::info!(
|
||||
"Received extension request: {}",
|
||||
@@ -100,15 +103,6 @@ async fn add_extension(
|
||||
return Err(StatusCode::UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
};
|
||||
// Verify the presence and validity of the secret key.
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
// If this is a Stdio extension that uses npx, check for Node.js installation
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -264,15 +258,7 @@ async fn remove_extension(
|
||||
headers: HeaderMap,
|
||||
Json(name): Json<String>,
|
||||
) -> Result<Json<ExtensionResponse>, StatusCode> {
|
||||
// Verify the presence and validity of the secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Acquire a lock on the agent and attempt to remove the extension
|
||||
let mut agent = state.agent.write().await;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::State,
|
||||
@@ -104,15 +105,7 @@ async fn handler(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<ChatRequest>,
|
||||
) -> Result<SseResponse, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Create channel for streaming
|
||||
let (tx, rx) = mpsc::channel(100);
|
||||
@@ -273,15 +266,7 @@ async fn ask_handler(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<AskRequest>,
|
||||
) -> Result<Json<AskResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let session_working_dir = request.session_working_dir;
|
||||
|
||||
@@ -393,15 +378,7 @@ pub async fn confirm_permission(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<PermissionConfirmationRequest>,
|
||||
) -> Result<Json<Value>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let agent = state.agent.clone();
|
||||
let agent = agent.read().await;
|
||||
@@ -437,6 +414,8 @@ async fn submit_tool_result(
|
||||
headers: HeaderMap,
|
||||
raw: axum::extract::Json<serde_json::Value>,
|
||||
) -> Result<Json<Value>, StatusCode> {
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
// Log the raw request for debugging
|
||||
tracing::info!(
|
||||
"Received tool result request: {}",
|
||||
@@ -456,16 +435,6 @@ async fn submit_tool_result(
|
||||
}
|
||||
};
|
||||
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
let agent = state.agent.read().await;
|
||||
let agent = agent.as_ref().ok_or(StatusCode::NOT_FOUND)?;
|
||||
agent.handle_tool_result(payload.id, payload.result).await;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::utils::verify_secret_key;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
@@ -27,15 +28,7 @@ async fn list_sessions(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Json<SessionListResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let sessions = get_session_info().map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
@@ -48,15 +41,7 @@ async fn get_session_history(
|
||||
headers: HeaderMap,
|
||||
Path(session_id): Path<String>,
|
||||
) -> Result<Json<SessionHistoryResponse>, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
verify_secret_key(&headers, &state)?;
|
||||
|
||||
let session_path = session::get_path(session::Identifier::Name(session_id.clone()));
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::state::AppState;
|
||||
use goose::config::Config;
|
||||
use goose::providers::base::{ConfigKey, ProviderMetadata};
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
@@ -21,6 +23,20 @@ pub struct KeyInfo {
|
||||
pub value: Option<String>, // Only populated for non-secret keys that are set
|
||||
}
|
||||
|
||||
pub fn verify_secret_key(headers: &HeaderMap, state: &AppState) -> Result<StatusCode, StatusCode> {
|
||||
// Verify secret key
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
if secret_key != state.secret_key {
|
||||
Err(StatusCode::UNAUTHORIZED)
|
||||
} else {
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
}
|
||||
|
||||
/// Inspects a configuration key to determine if it's set, its location, and value (for non-secret keys)
|
||||
#[allow(dead_code)]
|
||||
pub fn inspect_key(key_name: &str, is_secret: bool) -> Result<KeyInfo, Box<dyn Error>> {
|
||||
|
||||
Reference in New Issue
Block a user