allow returning strings from CEL as shorthand

This commit is contained in:
aecsocket
2026-08-13 18:12:46 +00:00
parent 43818e4f90
commit ac00e2bd5d
4 changed files with 22 additions and 9 deletions
@@ -46,8 +46,8 @@
</div>
</div>
<p class="m-0 text-sm text-secondary">
Return <code>null</code> when the rule does not match, or a map containing
<code>severity</code> when it does.
Return <code>null</code> when the rule does not match, or return a severity string such as
<code>"low"</code>. A map containing <code>severity</code> is also supported.
</p>
<details class="rounded-xl border border-divider bg-bg-raised p-3">
@@ -433,7 +433,7 @@ import type { Component } from 'vue'
import IssueDetailPath from '~/components/ui/moderation/IssueDetailPath.vue'
const DEFAULT_RULE = `trace.issue_type == "OBFUSCATED_NAMES"
? {"severity": "low"}
? "low"
: null`
const RULE_EDITOR_OPTIONS: Partial<Ace.EditorOptions> = {
useWorker: false,
@@ -216,7 +216,7 @@ INSERT INTO delphi_rules (name, rule, priority, revision)
VALUES
(
'[DEV trace-rule fixture] Escalate known malware host',
'trace.issue_type == "SUSPICIOUS_NETWORK_ACCESS" && trace.data.host == "evil.example" ? {"severity": "malware"} : null',
'trace.issue_type == "SUSPICIOUS_NETWORK_ACCESS" && trace.data.host == "evil.example" ? "malware" : null',
1000,
(SELECT revision FROM delphi_rule_revisions LIMIT 1)
),
@@ -234,7 +234,7 @@ VALUES
),
(
'[DEV trace-rule fixture] Hide known-safe obfuscation',
'trace.issue_type == "OBFUSCATED_NAMES" && trace.data.confidence >= 0.95 ? {"severity": "hidden"} : null',
'trace.issue_type == "OBFUSCATED_NAMES" && trace.data.confidence >= 0.95 ? "hidden" : null',
700,
(SELECT revision FROM delphi_rule_revisions LIMIT 1)
),
@@ -252,7 +252,7 @@ VALUES
),
(
'[DEV trace-rule fixture] Downgrade bundled libraries',
'trace.issue_type == "BUNDLED_LIBRARY" ? {"severity": "low"} : null',
'trace.issue_type == "BUNDLED_LIBRARY" ? "low" : null',
400,
(SELECT revision FROM delphi_rule_revisions LIMIT 1)
),
@@ -97,6 +97,13 @@ pub struct DelphiRuleEffect {
pub severity: DelphiSeverity,
}
#[derive(Serialize, utoipa::ToSchema)]
#[serde(untagged)]
pub enum DelphiRuleOutput {
Severity(DelphiSeverity),
Effect(DelphiRuleEffect),
}
struct ValidatedRule {
name: String,
rule: String,
@@ -12,7 +12,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
use utoipa::{PartialSchema, ToSchema};
use xredis::RedisPool;
use super::rules::DelphiRuleEffect;
use super::rules::{DelphiRuleEffect, DelphiRuleOutput};
use crate::routes::internal::delphi::tech_review_queue::{
self, TechReviewRemovalReason,
};
@@ -156,12 +156,12 @@ pub async fn get_rule_schema(
let mut schemas = Vec::new();
<RuleInput as ToSchema>::schemas(&mut schemas);
<Option<DelphiRuleEffect> as ToSchema>::schemas(&mut schemas);
<Option<DelphiRuleOutput> as ToSchema>::schemas(&mut schemas);
Ok(web::Json(DelphiRuleSchemaResponse {
input: schema_to_value(<RuleInput as PartialSchema>::schema())?,
output: schema_to_value(
<Option<DelphiRuleEffect> as PartialSchema>::schema(),
<Option<DelphiRuleOutput> as PartialSchema>::schema(),
)?,
components: schemas
.into_iter()
@@ -972,6 +972,12 @@ fn evaluate_rule_inner(
match value {
serde_json::Value::Null => Ok(None),
serde_json::Value::String(severity) => {
let severity =
serde_json::from_value(serde_json::Value::String(severity))
.wrap_err("cel expression returned an invalid severity")?;
Ok(Some(DelphiRuleEffect { severity }))
}
value => serde_json::from_value(value)
.map(Some)
.wrap_err("cel expression returned an invalid rule effect"),