///|
pub struct PayloadRule {
key : String
required : Bool
expected_value : String
} derive(Eq, Debug)
///|
pub fn PayloadRule::new(
key : String,
required? : Bool = true,
expected_value? : String = "",
) -> PayloadRule {
{ key, required, expected_value }
}
///|
pub struct PayloadSchema {
name : String
rules : Array[PayloadRule]
} derive(Eq, Debug)
///|
pub fn PayloadSchema::new(
name : String,
rules : Array[PayloadRule],
) -> PayloadSchema {
{ name, rules }
}
///|
pub struct PayloadValidationError {
key : String
message : String
} derive(Eq, Debug)
///|
pub fn PayloadValidationError::new(
key : String,
message : String,
) -> PayloadValidationError {
{ key, message }
}
///|
pub fn validate_payload_schema(
schema : PayloadSchema,
fields : Array[PayloadField],
) -> Array[PayloadValidationError] {
let mut count = 0
for i in 0.. if value != rule.expected_value { count = count + 1 }
None => ()
}
}
}
let mut offset = 0
Array::makei(count, _ => {
while offset < schema.rules.length() {
let rule = schema.rules[offset]
offset = offset + 1
let found = payload_value(fields, rule.key)
if rule.required && found is None {
return PayloadValidationError::new(rule.key, "required field missing")
}
if rule.expected_value != "" {
match found {
Some(value) =>
if value != rule.expected_value {
return PayloadValidationError::new(rule.key, "unexpected value")
}
None => ()
}
}
}
PayloadValidationError::new("", "")
})
}
///|
pub fn schema_is_valid(schema : PayloadSchema, body : String) -> Bool {
validate_payload_schema(schema, parse_payload_fields(body)).length() == 0
}
///|
pub fn github_issue_schema() -> PayloadSchema {
PayloadSchema::new("github_issue", [PayloadRule::new("action")])
}
///|
pub fn feishu_message_schema() -> PayloadSchema {
PayloadSchema::new("feishu_message", [PayloadRule::new("event")])
}
///|
pub fn schema_for_event(
provider : String,
event_type : String,
) -> PayloadSchema? {
if provider == "github" && event_type == "issues" {
Some(github_issue_schema())
} else if provider == "feishu" && event_type == "im.message.receive_v1" {
Some(feishu_message_schema())
} else {
None
}
}
///|
pub fn validate_request_payload(
request : WebhookRequest,
profile : ProviderProfile,
) -> Array[PayloadValidationError] {
match schema_for_event(profile.name, provider_event_type(request, profile)) {
Some(schema) =>
validate_payload_schema(schema, parse_payload_fields(request.body))
None => []
}
}
///|
pub fn payload_error_text(errors : Array[PayloadValidationError]) -> String {
let builder = StringBuilder::new()
for i in 0..