auths_sdk/workflows/
diagnostics.rs1use crate::ports::diagnostics::{
4 CheckResult, ConfigIssue, CryptoDiagnosticProvider, DiagnosticError, DiagnosticReport,
5 GitDiagnosticProvider,
6};
7
8pub struct DiagnosticsWorkflow<G: GitDiagnosticProvider, C: CryptoDiagnosticProvider> {
20 git: G,
21 crypto: C,
22}
23
24impl<G: GitDiagnosticProvider, C: CryptoDiagnosticProvider> DiagnosticsWorkflow<G, C> {
25 pub fn new(git: G, crypto: C) -> Self {
27 Self { git, crypto }
28 }
29
30 pub fn run(&self) -> Result<DiagnosticReport, DiagnosticError> {
38 let mut checks = Vec::new();
39
40 checks.push(self.git.check_git_version()?);
41 checks.push(self.crypto.check_ssh_keygen_available()?);
42
43 self.check_git_signing_config(&mut checks)?;
44
45 Ok(DiagnosticReport { checks })
46 }
47
48 fn check_git_signing_config(
49 &self,
50 checks: &mut Vec<CheckResult>,
51 ) -> Result<(), DiagnosticError> {
52 let required = [
53 ("gpg.format", "ssh"),
54 ("commit.gpgsign", "true"),
55 ("tag.gpgsign", "true"),
56 ];
57 let presence_only = ["user.signingkey", "gpg.ssh.program"];
58
59 let mut issues: Vec<ConfigIssue> = Vec::new();
60
61 for (key, expected) in &required {
62 match self.git.get_git_config(key)? {
63 Some(val) if val == *expected => {}
64 Some(actual) => {
65 issues.push(ConfigIssue::Mismatch {
66 key: key.to_string(),
67 expected: expected.to_string(),
68 actual,
69 });
70 }
71 None => {
72 issues.push(ConfigIssue::Absent(key.to_string()));
73 }
74 }
75 }
76
77 for key in &presence_only {
78 if self.git.get_git_config(key)?.is_none() {
79 issues.push(ConfigIssue::Absent(key.to_string()));
80 }
81 }
82
83 let passed = issues.is_empty();
84
85 checks.push(CheckResult {
86 name: "Git signing config".to_string(),
87 passed,
88 message: None,
89 config_issues: issues,
90 });
91
92 Ok(())
93 }
94}