一、模型与输入type SecurityScheme = { type: 'http' | 'apiKey' | 'oauth2'; name?: string; scheme?: string }
type Operation = { security?: string[]; parameters?: { name: string; in: 'query' | 'header' | 'path' | 'cookie'; required?: boolean; schema?: { type: 'string' | 'number' | 'boolean'; min?: number; max?: number } }[] }
type PathItem = { [method: string]: Operation }
type OpenApiDoc = { securitySchemes: Record<string, SecurityScheme>; paths: Record<string, PathItem> }
二、校验规则function hasSecurity(doc: OpenApiDoc, op: Operation): boolean {
const list = op.security || []
return list.every(k => !!doc.securitySchemes[k])
}
function validParam(p: Operation['parameters'][number]): boolean {
const s = p.schema
if (!s) return false
if (s.type === 'string') return true
if (s.type === 'number') return typeof s.min === 'number' && typeof s.max === 'number' && s.min <= s.max
if (s.type === 'boolean') return true
return false
}
function requiredOk(p: Operation['parameters'][number]): boolean {
if (p.in === 'path') return p.required === true
return true
}
三、扫描器与报告type Issue = { path: string; method: string; code: string; detail: string }
function scan(doc: OpenApiDoc): Issue[] {
const out: Issue[] = []
for (const [path, item] of Object.entries(doc.paths)) {
for (const [method, op] of Object.entries(item)) {
if (!hasSecurity(doc, op)) out.push({ path, method, code: 'missing_security', detail: 'operation without security' })
for (const p of op.parameters || []) {
if (!requiredOk(p)) out.push({ path, method, code: 'path_param_required', detail: p.name })
if (!validParam(p)) out.push({ path, method, code: 'param_invalid', detail: p.name })
}
}
}
return out
}
四、聚合与验收class Aggregator { counts = new Map<string, number>(); inc(k: string) { const n = (this.counts.get(k) || 0) + 1; this.counts.set(k, n) } top() { return Array.from(this.counts.entries()).sort((a,b)=>b[1]-a[1]) } }
function aggregate(issues: Issue[]): Aggregator { const agg = new Aggregator(); for (const i of issues) agg.inc(i.code); return agg }
所有操作声明安全方案并存在;路径参数标记`required=true`;数字参数具备最小最大范围。报告聚合包含问题码与计数;输出按路径与方法可定位;可作为CI检查的一部分。

发表评论 取消回复