Skip to main content

vault_core/
templates.rs

1//! Secret templates: predefined field presets for common services (a GitHub PAT,
2//! an AWS key, a Postgres DSN). One JSON file at the repo root,
3//! `secret-templates.json`, compiled in here and imported by the app's
4//! Templates pane, so `unv entry add --template ID` and the pane offer the same
5//! presets (Phase 33.6).
6
7use serde::Deserialize;
8use serde_json::Value;
9
10const RAW: &str = include_str!("../../secret-templates.json");
11
12#[derive(Debug, Clone, Deserialize)]
13pub struct Template {
14    pub id: String,
15    pub name: String,
16    pub icon: String,
17    pub category: String,
18    #[serde(rename = "secretType")]
19    pub secret_type: String,
20    /// Entry fields the template pre-fills.
21    pub defaults: serde_json::Map<String, Value>,
22    #[serde(rename = "requiredFields", default)]
23    pub required_fields: Vec<String>,
24    #[serde(default)]
25    pub hints: serde_json::Map<String, Value>,
26}
27
28#[derive(Deserialize)]
29struct File {
30    templates: Vec<Template>,
31}
32
33pub fn list() -> Vec<Template> {
34    serde_json::from_str::<File>(RAW)
35        .expect("secret-templates.json failed to parse: a build-time defect")
36        .templates
37}
38
39pub fn find(id: &str) -> Option<Template> {
40    list().into_iter().find(|t| t.id.eq_ignore_ascii_case(id))
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn every_template_parses_and_has_a_known_type() {
49        let all = list();
50        assert!(all.len() >= 10);
51        for t in &all {
52            assert!(
53                crate::secret_types::find(&t.secret_type).is_some(),
54                "{}: unknown secretType {}",
55                t.id,
56                t.secret_type
57            );
58            assert!(!t.defaults.is_empty(), "{} pre-fills nothing", t.id);
59        }
60        let mut ids: Vec<_> = all.iter().map(|t| t.id.clone()).collect();
61        ids.sort();
62        ids.dedup();
63        assert_eq!(ids.len(), all.len(), "duplicate template id");
64    }
65
66    #[test]
67    fn find_is_case_insensitive() {
68        assert_eq!(find("GitHub-PAT").unwrap().id, "github-pat");
69        assert!(find("nope").is_none());
70    }
71}