LCOV - code coverage report
Current view: top level - proxy/src/auth - mod.rs (source / functions) Coverage Total Hit
Test: 1b0a6a0c05cee5a7de360813c8034804e105ce1c.info Lines: 0.0 % 62 0
Test Date: 2025-03-12 00:01:28 Functions: 0.0 % 12 0

            Line data    Source code
       1              : //! Client authentication mechanisms.
       2              : 
       3              : pub mod backend;
       4              : pub use backend::Backend;
       5              : 
       6              : mod credentials;
       7              : pub(crate) use credentials::{
       8              :     ComputeUserInfoMaybeEndpoint, ComputeUserInfoParseError, IpPattern, check_peer_addr_is_in_list,
       9              :     endpoint_sni,
      10              : };
      11              : 
      12              : mod password_hack;
      13              : use password_hack::PasswordHackPayload;
      14              : pub(crate) use password_hack::parse_endpoint_param;
      15              : 
      16              : mod flow;
      17              : use std::io;
      18              : use std::net::IpAddr;
      19              : 
      20              : pub(crate) use flow::*;
      21              : use thiserror::Error;
      22              : use tokio::time::error::Elapsed;
      23              : 
      24              : use crate::auth::backend::jwt::JwtError;
      25              : use crate::control_plane;
      26              : use crate::error::{ReportableError, UserFacingError};
      27              : 
      28              : /// Convenience wrapper for the authentication error.
      29              : pub(crate) type Result<T> = std::result::Result<T, AuthError>;
      30              : 
      31              : /// Common authentication error.
      32              : #[derive(Debug, Error)]
      33              : pub(crate) enum AuthError {
      34              :     #[error(transparent)]
      35              :     ConsoleRedirect(#[from] backend::ConsoleRedirectError),
      36              : 
      37              :     #[error(transparent)]
      38              :     GetAuthInfo(#[from] control_plane::errors::GetAuthInfoError),
      39              : 
      40              :     /// SASL protocol errors (includes [SCRAM](crate::scram)).
      41              :     #[error(transparent)]
      42              :     Sasl(#[from] crate::sasl::Error),
      43              : 
      44              :     #[error("Unsupported authentication method: {0}")]
      45              :     BadAuthMethod(Box<str>),
      46              : 
      47              :     #[error("Malformed password message: {0}")]
      48              :     MalformedPassword(&'static str),
      49              : 
      50              :     #[error(
      51              :         "Endpoint ID is not specified. \
      52              :         Either please upgrade the postgres client library (libpq) for SNI support \
      53              :         or pass the endpoint ID (first part of the domain name) as a parameter: '?options=endpoint%3D<endpoint-id>'. \
      54              :         See more at https://neon.tech/sni"
      55              :     )]
      56              :     MissingEndpointName,
      57              : 
      58              :     #[error(
      59              :         "VPC endpoint ID is not specified. \
      60              :         This endpoint requires a VPC endpoint ID to connect."
      61              :     )]
      62              :     MissingVPCEndpointId,
      63              : 
      64              :     #[error("password authentication failed for user '{0}'")]
      65              :     PasswordFailed(Box<str>),
      66              : 
      67              :     /// Errors produced by e.g. [`crate::stream::PqStream`].
      68              :     #[error(transparent)]
      69              :     Io(#[from] io::Error),
      70              : 
      71              :     #[error(
      72              :         "This IP address {0} is not allowed to connect to this endpoint. \
      73              :         Please add it to the allowed list in the Neon console. \
      74              :         Make sure to check for IPv4 or IPv6 addresses."
      75              :     )]
      76              :     IpAddressNotAllowed(IpAddr),
      77              : 
      78              :     #[error("This connection is trying to access this endpoint from a blocked network.")]
      79              :     NetworkNotAllowed,
      80              : 
      81              :     #[error(
      82              :         "This VPC endpoint id {0} is not allowed to connect to this endpoint. \
      83              :         Please add it to the allowed list in the Neon console."
      84              :     )]
      85              :     VpcEndpointIdNotAllowed(String),
      86              : 
      87              :     #[error("Too many connections to this endpoint. Please try again later.")]
      88              :     TooManyConnections,
      89              : 
      90              :     #[error("Authentication timed out")]
      91              :     UserTimeout(Elapsed),
      92              : 
      93              :     #[error("Disconnected due to inactivity after {0}.")]
      94              :     ConfirmationTimeout(humantime::Duration),
      95              : 
      96              :     #[error(transparent)]
      97              :     Jwt(#[from] JwtError),
      98              : }
      99              : 
     100              : impl AuthError {
     101            0 :     pub(crate) fn bad_auth_method(name: impl Into<Box<str>>) -> Self {
     102            0 :         AuthError::BadAuthMethod(name.into())
     103            0 :     }
     104              : 
     105            0 :     pub(crate) fn password_failed(user: impl Into<Box<str>>) -> Self {
     106            0 :         AuthError::PasswordFailed(user.into())
     107            0 :     }
     108              : 
     109            0 :     pub(crate) fn ip_address_not_allowed(ip: IpAddr) -> Self {
     110            0 :         AuthError::IpAddressNotAllowed(ip)
     111            0 :     }
     112              : 
     113            0 :     pub(crate) fn vpc_endpoint_id_not_allowed(id: String) -> Self {
     114            0 :         AuthError::VpcEndpointIdNotAllowed(id)
     115            0 :     }
     116              : 
     117            0 :     pub(crate) fn too_many_connections() -> Self {
     118            0 :         AuthError::TooManyConnections
     119            0 :     }
     120              : 
     121            0 :     pub(crate) fn is_password_failed(&self) -> bool {
     122            0 :         matches!(self, AuthError::PasswordFailed(_))
     123            0 :     }
     124              : 
     125            0 :     pub(crate) fn user_timeout(elapsed: Elapsed) -> Self {
     126            0 :         AuthError::UserTimeout(elapsed)
     127            0 :     }
     128              : 
     129            0 :     pub(crate) fn confirmation_timeout(timeout: humantime::Duration) -> Self {
     130            0 :         AuthError::ConfirmationTimeout(timeout)
     131            0 :     }
     132              : }
     133              : 
     134              : impl UserFacingError for AuthError {
     135            0 :     fn to_string_client(&self) -> String {
     136            0 :         match self {
     137            0 :             Self::ConsoleRedirect(e) => e.to_string_client(),
     138            0 :             Self::GetAuthInfo(e) => e.to_string_client(),
     139            0 :             Self::Sasl(e) => e.to_string_client(),
     140            0 :             Self::PasswordFailed(_) => self.to_string(),
     141            0 :             Self::BadAuthMethod(_) => self.to_string(),
     142            0 :             Self::MalformedPassword(_) => self.to_string(),
     143            0 :             Self::MissingEndpointName => self.to_string(),
     144            0 :             Self::MissingVPCEndpointId => self.to_string(),
     145            0 :             Self::Io(_) => "Internal error".to_string(),
     146            0 :             Self::IpAddressNotAllowed(_) => self.to_string(),
     147            0 :             Self::NetworkNotAllowed => self.to_string(),
     148            0 :             Self::VpcEndpointIdNotAllowed(_) => self.to_string(),
     149            0 :             Self::TooManyConnections => self.to_string(),
     150            0 :             Self::UserTimeout(_) => self.to_string(),
     151            0 :             Self::ConfirmationTimeout(_) => self.to_string(),
     152            0 :             Self::Jwt(_) => self.to_string(),
     153              :         }
     154            0 :     }
     155              : }
     156              : 
     157              : impl ReportableError for AuthError {
     158            0 :     fn get_error_kind(&self) -> crate::error::ErrorKind {
     159            0 :         match self {
     160            0 :             Self::ConsoleRedirect(e) => e.get_error_kind(),
     161            0 :             Self::GetAuthInfo(e) => e.get_error_kind(),
     162            0 :             Self::Sasl(e) => e.get_error_kind(),
     163            0 :             Self::PasswordFailed(_) => crate::error::ErrorKind::User,
     164            0 :             Self::BadAuthMethod(_) => crate::error::ErrorKind::User,
     165            0 :             Self::MalformedPassword(_) => crate::error::ErrorKind::User,
     166            0 :             Self::MissingEndpointName => crate::error::ErrorKind::User,
     167            0 :             Self::MissingVPCEndpointId => crate::error::ErrorKind::User,
     168            0 :             Self::Io(_) => crate::error::ErrorKind::ClientDisconnect,
     169            0 :             Self::IpAddressNotAllowed(_) => crate::error::ErrorKind::User,
     170            0 :             Self::NetworkNotAllowed => crate::error::ErrorKind::User,
     171            0 :             Self::VpcEndpointIdNotAllowed(_) => crate::error::ErrorKind::User,
     172            0 :             Self::TooManyConnections => crate::error::ErrorKind::RateLimit,
     173            0 :             Self::UserTimeout(_) => crate::error::ErrorKind::User,
     174            0 :             Self::ConfirmationTimeout(_) => crate::error::ErrorKind::User,
     175            0 :             Self::Jwt(_) => crate::error::ErrorKind::User,
     176              :         }
     177            0 :     }
     178              : }
        

Generated by: LCOV version 2.1-beta