add check for action and bot_name
This commit is contained in:
+101
-12
@@ -18,6 +18,7 @@ pub struct ReviewPayload {
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct PullRequest {
|
||||
pub id: u64,
|
||||
pub diff_url: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
@@ -33,11 +34,29 @@ pub struct User {
|
||||
}
|
||||
|
||||
impl WebhookType {
|
||||
pub fn from_event(event: &str, json: Value) -> Result<Self, AppError> {
|
||||
match event {
|
||||
pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result<Self, AppError> {
|
||||
let wb = match event {
|
||||
"pull_request_comment" => Ok(WebhookType::Review(serde_json::from_value(json)?)),
|
||||
_ => Err(AppError::UnknownEventErr),
|
||||
}?;
|
||||
|
||||
let pr_body = match &wb {
|
||||
WebhookType::Review(review_payload) => &review_payload.comment.body,
|
||||
};
|
||||
|
||||
if !pr_body.starts_with(&format!("@{}", bot_name)) {
|
||||
return Err(AppError::UnauthorizedUserErr);
|
||||
}
|
||||
|
||||
let action = match &wb {
|
||||
WebhookType::Review(review_payload) => &review_payload.action,
|
||||
};
|
||||
|
||||
if action != "created" {
|
||||
return Err(AppError::InvalidActionErr);
|
||||
}
|
||||
|
||||
Ok(wb)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,18 +70,19 @@ mod tests {
|
||||
let json = json!({
|
||||
"action": "created",
|
||||
"pull_request": {
|
||||
"id": 42
|
||||
"id": 42,
|
||||
"diff_url": "https://mydiff.fr"
|
||||
},
|
||||
"comment": {
|
||||
"id": 7,
|
||||
"body": "LGTM",
|
||||
"body": "@test_bot LGTM",
|
||||
"user": {
|
||||
"id": 100
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let result = WebhookType::from_event("pull_request_comment", json);
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json);
|
||||
assert!(result.is_ok());
|
||||
|
||||
match result.unwrap() {
|
||||
@@ -70,7 +90,7 @@ mod tests {
|
||||
assert_eq!(payload.action, "created");
|
||||
assert_eq!(payload.pull_request.id, 42);
|
||||
assert_eq!(payload.comment.id, 7);
|
||||
assert_eq!(payload.comment.body, "LGTM");
|
||||
assert_eq!(payload.comment.body, "@test_bot LGTM");
|
||||
assert_eq!(payload.comment.user.id, 100);
|
||||
}
|
||||
}
|
||||
@@ -79,7 +99,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_from_event_unknown_event() {
|
||||
let json = json!({});
|
||||
let result = WebhookType::from_event("push", json);
|
||||
let result = WebhookType::from_event("push", "test_bot", json);
|
||||
assert!(result.is_err());
|
||||
|
||||
match result.unwrap_err() {
|
||||
@@ -95,7 +115,7 @@ mod tests {
|
||||
// pull_request and comment are missing
|
||||
});
|
||||
|
||||
let result = WebhookType::from_event("pull_request_comment", json);
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json);
|
||||
assert!(result.is_err());
|
||||
|
||||
match result.unwrap_err() {
|
||||
@@ -105,11 +125,38 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_review_payload() {
|
||||
fn test_from_event_rejects_non_created_action() {
|
||||
let json = json!({
|
||||
"action": "edited",
|
||||
"pull_request": {
|
||||
"id": 99
|
||||
"id": 1,
|
||||
"diff_url": "https://mydiff.fr"
|
||||
},
|
||||
"comment": {
|
||||
"id": 1,
|
||||
"body": "@test_bot body",
|
||||
"user": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json);
|
||||
assert!(result.is_err());
|
||||
|
||||
match result.unwrap_err() {
|
||||
AppError::InvalidActionErr => {}
|
||||
_ => panic!("expected InvalidActionErr"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_review_payload() {
|
||||
let json = json!({
|
||||
"action": "created",
|
||||
"pull_request": {
|
||||
"id": 99,
|
||||
"diff_url": "https://mydiff.fr"
|
||||
},
|
||||
"comment": {
|
||||
"id": 12,
|
||||
@@ -121,7 +168,7 @@ mod tests {
|
||||
});
|
||||
|
||||
let payload: ReviewPayload = serde_json::from_value(json).unwrap();
|
||||
assert_eq!(payload.action, "edited");
|
||||
assert_eq!(payload.action, "created");
|
||||
assert_eq!(payload.pull_request.id, 99);
|
||||
assert_eq!(payload.comment.id, 12);
|
||||
assert_eq!(payload.comment.body, "Needs work");
|
||||
@@ -130,8 +177,50 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_from_event_empty_json() {
|
||||
let result = WebhookType::from_event("pull_request_comment", json!({}));
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json!({}));
|
||||
assert!(result.is_err());
|
||||
assert!(matches!(result.unwrap_err(), AppError::BadJsonStructErr(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_event_rejects_wrong_bot_name() {
|
||||
let json = json!({
|
||||
"action": "created",
|
||||
"pull_request": {
|
||||
"id": 1,
|
||||
"diff_url": "https://mydiff.fr"
|
||||
},
|
||||
"comment": {
|
||||
"id": 1,
|
||||
"body": "@other_bot do something",
|
||||
"user": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json);
|
||||
assert!(matches!(result.unwrap_err(), AppError::UnauthorizedUserErr));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_event_rejects_no_bot_prefix() {
|
||||
let json = json!({
|
||||
"action": "created",
|
||||
"pull_request": {
|
||||
"id": 1,
|
||||
"diff_url": "https://mydiff.fr"
|
||||
},
|
||||
"comment": {
|
||||
"id": 1,
|
||||
"body": "just a comment without bot mention",
|
||||
"user": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let result = WebhookType::from_event("pull_request_comment", "test_bot", json);
|
||||
assert!(matches!(result.unwrap_err(), AppError::UnauthorizedUserErr));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user