use thiserror::Error;
use crate::error::AuthsErrorInfo;
#[derive(Error, Debug)]
pub enum CommitVerificationError {
#[error("commit is unsigned")]
UnsignedCommit,
#[error("GPG signatures not supported, use SSH signing")]
GpgNotSupported,
#[error("SSHSIG parse failed: {0}")]
SshSigParseFailed(String),
#[error("unsupported SSH key type: {found}")]
UnsupportedKeyType {
found: String,
},
#[error("namespace mismatch: expected \"{expected}\", found \"{found}\"")]
NamespaceMismatch {
expected: String,
found: String,
},
#[error("unsupported hash algorithm: {0}")]
HashAlgorithmUnsupported(String),
#[error("signature verification failed")]
SignatureInvalid,
#[error("signer key not in allowed keys")]
UnknownSigner,
#[error("commit parse failed: {0}")]
CommitParseFailed(String),
}
impl AuthsErrorInfo for CommitVerificationError {
fn error_code(&self) -> &'static str {
match self {
Self::UnsignedCommit => "AUTHS-E2101",
Self::GpgNotSupported => "AUTHS-E2102",
Self::SshSigParseFailed(_) => "AUTHS-E2103",
Self::UnsupportedKeyType { .. } => "AUTHS-E2104",
Self::NamespaceMismatch { .. } => "AUTHS-E2105",
Self::HashAlgorithmUnsupported(_) => "AUTHS-E2106",
Self::SignatureInvalid => "AUTHS-E2107",
Self::UnknownSigner => "AUTHS-E2108",
Self::CommitParseFailed(_) => "AUTHS-E2109",
}
}
fn suggestion(&self) -> Option<&'static str> {
match self {
Self::UnsignedCommit => Some("Sign commits with: git commit -S"),
Self::GpgNotSupported => Some("Configure SSH signing: git config gpg.format ssh"),
Self::UnsupportedKeyType { .. } => {
Some("Use an Ed25519 or ECDSA P-256 SSH key for signing")
}
Self::UnknownSigner => Some("Add the signer's key to the allowed signers list"),
Self::SshSigParseFailed(_) => Some(
"The SSH signature could not be parsed; verify the commit was signed correctly",
),
Self::NamespaceMismatch { .. } => Some(
"The signature namespace doesn't match; ensure git config gpg.ssh.defaultKeyCommand is set correctly",
),
Self::HashAlgorithmUnsupported(_) => {
Some("Use SHA-256 or SHA-512 hash algorithm for signing")
}
Self::SignatureInvalid => Some(
"The commit signature does not match the signed data; the commit may have been modified after signing",
),
Self::CommitParseFailed(_) => Some(
"The Git commit object is malformed; check repository integrity with `git fsck`",
),
}
}
}