//! Client authentication mechanisms. pub mod backend; pub use backend::BackendType; mod credentials; pub use credentials::ClientCredentials; mod password_hack; pub use password_hack::parse_endpoint_param; use password_hack::PasswordHackPayload; mod flow; pub use flow::*; use crate::{console, error::UserFacingError}; use std::io; use thiserror::Error; /// Convenience wrapper for the authentication error. pub type Result = std::result::Result; /// Common authentication error. #[derive(Debug, Error)] pub enum AuthErrorImpl { #[error(transparent)] Link(#[from] backend::LinkAuthError), #[error(transparent)] GetAuthInfo(#[from] console::errors::GetAuthInfoError), #[error(transparent)] WakeCompute(#[from] console::errors::WakeComputeError), /// SASL protocol errors (includes [SCRAM](crate::scram)). #[error(transparent)] Sasl(#[from] crate::sasl::Error), #[error("Unsupported authentication method: {0}")] BadAuthMethod(Box), #[error("Malformed password message: {0}")] MalformedPassword(&'static str), #[error( "Endpoint ID is not specified. \ Either please upgrade the postgres client library (libpq) for SNI support \ or pass the endpoint ID (first part of the domain name) as a parameter: '?options=endpoint%3D'. \ See more at https://neon.tech/sni" )] MissingEndpointName, #[error("password authentication failed for user '{0}'")] AuthFailed(Box), /// Errors produced by e.g. [`crate::stream::PqStream`]. #[error(transparent)] Io(#[from] io::Error), } #[derive(Debug, Error)] #[error(transparent)] pub struct AuthError(Box); impl AuthError { pub fn bad_auth_method(name: impl Into>) -> Self { AuthErrorImpl::BadAuthMethod(name.into()).into() } pub fn auth_failed(user: impl Into>) -> Self { AuthErrorImpl::AuthFailed(user.into()).into() } } impl> From for AuthError { fn from(e: E) -> Self { Self(Box::new(e.into())) } } impl UserFacingError for AuthError { fn to_string_client(&self) -> String { use AuthErrorImpl::*; match self.0.as_ref() { Link(e) => e.to_string_client(), GetAuthInfo(e) => e.to_string_client(), WakeCompute(e) => e.to_string_client(), Sasl(e) => e.to_string_client(), AuthFailed(_) => self.to_string(), BadAuthMethod(_) => self.to_string(), MalformedPassword(_) => self.to_string(), MissingEndpointName => self.to_string(), Io(_) => "Internal error".to_string(), } } }