fix: pre-release audit fixes — Twitter OAuth, DataMasking perf, Prompt versioning
- Twitter like/retweet: return explicit unavailable error instead of sending doomed Bearer token requests (would 403 on Twitter API v2) - DataMasking: pre-compile regex patterns with LazyLock (was compiling 6 patterns on every mask() call) - Prompt version: fix get_version handler ignoring version path param, add service::get_version_by_number for correct per-version retrieval
This commit is contained in:
@@ -497,62 +497,34 @@ impl TwitterHand {
|
||||
}
|
||||
|
||||
/// Execute like action — PUT /2/users/:id/likes
|
||||
///
|
||||
/// **NOTE**: Twitter API v2 requires OAuth 1.0a user context for like/retweet.
|
||||
/// Bearer token (app-only auth) is not sufficient and will return 403.
|
||||
/// This action is currently unavailable until OAuth 1.0a signing is implemented.
|
||||
async fn execute_like(&self, tweet_id: &str) -> Result<Value> {
|
||||
let creds = self.get_credentials().await
|
||||
.ok_or_else(|| zclaw_types::ZclawError::HandError("Twitter credentials not configured".to_string()))?;
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
// Note: For like/retweet, we need OAuth 1.0a user context
|
||||
// Using Bearer token as fallback (may not work for all endpoints)
|
||||
let url = "https://api.twitter.com/2/users/me/likes";
|
||||
|
||||
let response = client.post(url)
|
||||
.header("Authorization", format!("Bearer {}", creds.bearer_token.as_deref().unwrap_or("")))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("User-Agent", "ZCLAW/1.0")
|
||||
.json(&json!({"tweet_id": tweet_id}))
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| zclaw_types::ZclawError::HandError(format!("Like failed: {}", e)))?;
|
||||
|
||||
let status = response.status();
|
||||
let response_text = response.text().await.unwrap_or_default();
|
||||
|
||||
let _ = tweet_id;
|
||||
tracing::warn!("[TwitterHand] like action requires OAuth 1.0a user context — not yet supported");
|
||||
Ok(json!({
|
||||
"success": status.is_success(),
|
||||
"tweet_id": tweet_id,
|
||||
"action": "liked",
|
||||
"status_code": status.as_u16(),
|
||||
"message": if status.is_success() { "Tweet liked" } else { &response_text }
|
||||
"success": false,
|
||||
"action": "like",
|
||||
"error": "OAuth 1.0a user context required. Like action is not yet supported with app-only Bearer token.",
|
||||
"suggestion": "Configure OAuth 1.0a credentials (access_token + access_token_secret) to enable write actions."
|
||||
}))
|
||||
}
|
||||
|
||||
/// Execute retweet action — POST /2/users/:id/retweets
|
||||
///
|
||||
/// **NOTE**: Twitter API v2 requires OAuth 1.0a user context for retweet.
|
||||
/// Bearer token (app-only auth) is not sufficient and will return 403.
|
||||
/// This action is currently unavailable until OAuth 1.0a signing is implemented.
|
||||
async fn execute_retweet(&self, tweet_id: &str) -> Result<Value> {
|
||||
let creds = self.get_credentials().await
|
||||
.ok_or_else(|| zclaw_types::ZclawError::HandError("Twitter credentials not configured".to_string()))?;
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let url = "https://api.twitter.com/2/users/me/retweets";
|
||||
|
||||
let response = client.post(url)
|
||||
.header("Authorization", format!("Bearer {}", creds.bearer_token.as_deref().unwrap_or("")))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("User-Agent", "ZCLAW/1.0")
|
||||
.json(&json!({"tweet_id": tweet_id}))
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| zclaw_types::ZclawError::HandError(format!("Retweet failed: {}", e)))?;
|
||||
|
||||
let status = response.status();
|
||||
let response_text = response.text().await.unwrap_or_default();
|
||||
|
||||
let _ = tweet_id;
|
||||
tracing::warn!("[TwitterHand] retweet action requires OAuth 1.0a user context — not yet supported");
|
||||
Ok(json!({
|
||||
"success": status.is_success(),
|
||||
"tweet_id": tweet_id,
|
||||
"action": "retweeted",
|
||||
"status_code": status.as_u16(),
|
||||
"message": if status.is_success() { "Tweet retweeted" } else { &response_text }
|
||||
"success": false,
|
||||
"action": "retweet",
|
||||
"error": "OAuth 1.0a user context required. Retweet action is not yet supported with app-only Bearer token.",
|
||||
"suggestion": "Configure OAuth 1.0a credentials (access_token + access_token_secret) to enable write actions."
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user