限制错误报告创建身份与频率

创建 procedure 增加服务身份校验

增加单 identity 每小时 100 次提交配额并保留幂等重试
This commit is contained in:
2026-09-02 19:05:04 +08:00
parent 733939269f
commit ae83e3679c
@@ -2,6 +2,8 @@ use crate::*;
const MAX_FIELD_CHARS: usize = 512;
const MAX_NOTE_CHARS: usize = 2_000;
const MAX_REPORTS_PER_IDENTITY_PER_HOUR: usize = 100;
const REPORT_QUOTA_WINDOW_MICROS: i64 = 60 * 60 * 1_000_000;
#[spacetimedb::table(
accessor = error_report,
@@ -142,8 +144,12 @@ pub fn create_error_report_and_return(
input: ErrorReportCreateInput,
) -> ErrorReportProcedureResult {
let caller_user_id = ctx.sender().to_hex().to_string();
let caller = ctx.sender();
let now = ctx.timestamp;
match ctx.try_with_tx(|tx| {
crate::editor_project_storage::require_editor_generation_runtime_service_identity(
tx, caller,
)?;
let batch_id = validate_text(&input.batch_id, "batch_id")?;
let user_id = validate_text(&caller_user_id, "user_id")?;
let submission_id = validate_text(&input.submission_id, "submission_id")?;
@@ -171,6 +177,21 @@ pub fn create_error_report_and_return(
if tx.db.error_report().batch_id().find(&batch_id).is_some() {
return Err("错误报告 batch_id 已存在".to_string());
}
let cutoff_micros = now
.to_micros_since_unix_epoch()
.saturating_sub(REPORT_QUOTA_WINDOW_MICROS);
let recent_count = tx
.db
.error_report()
.iter()
.filter(|row| {
row.user_id == user_id
&& row.created_at.to_micros_since_unix_epoch() >= cutoff_micros
})
.count();
if recent_count >= MAX_REPORTS_PER_IDENTITY_PER_HOUR {
return Err("错误报告提交频率超出限制,请稍后再试".to_string());
}
tx.db.error_report().insert(ErrorReport {
batch_id: batch_id.clone(),
user_id,