use thiserror::Error;
pub type Result<T> = std::result::Result<T, SessionError>;
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum SessionError {
#[error(transparent)]
Config(#[from] ConfigError),
#[error(transparent)]
Token(#[from] TokenError),
#[error(transparent)]
Renewal(#[from] RenewalError),
#[error(transparent)]
Repository(#[from] RepositoryError),
#[error(transparent)]
Revocation(#[from] RevocationError),
#[error("{message}")]
Unimplemented {
message: String,
},
}
impl SessionError {
pub fn unimplemented(message: impl Into<String>) -> Self {
Self::Unimplemented {
message: message.into(),
}
}
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum ConfigError {
#[error("invalid session configuration")]
Invalid,
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum TokenError {
#[error("failed to generate token material")]
GenerationFailed,
#[error("failed to hash token material")]
HashFailed,
#[error("failed to issue auth token")]
AuthIssuanceFailed,
#[error("invalid token material")]
InvalidTokenMaterial,
#[error("invalid refresh token length")]
InvalidRefreshTokenLength,
#[error("token operation failed")]
Failed,
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum RenewalError {
#[error("session is not eligible for renewal")]
NotEligible,
#[error("renewal lease unavailable")]
LeaseUnavailable,
#[error("refresh token replay detected")]
ReplayDetected,
#[error("session rotation failed")]
RotationFailed,
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum RepositoryError {
#[error("session not found")]
SessionNotFound,
#[error("session family not found")]
SessionFamilyNotFound,
#[error("concurrent session update detected")]
Conflict,
#[error("invalid persisted session state")]
InvalidState,
#[error("{message}")]
Backend {
message: String,
},
}
impl RepositoryError {
pub fn backend(message: impl Into<String>) -> Self {
Self::Backend {
message: message.into(),
}
}
}
impl From<crate::repository::RepositoryError> for RepositoryError {
fn from(value: crate::repository::RepositoryError) -> Self {
match value {
crate::repository::RepositoryError::SessionNotFound => Self::SessionNotFound,
crate::repository::RepositoryError::SessionFamilyNotFound => {
Self::SessionFamilyNotFound
}
crate::repository::RepositoryError::Conflict => Self::Conflict,
crate::repository::RepositoryError::InvalidState => Self::InvalidState,
crate::repository::RepositoryError::Backend { message } => Self::Backend { message },
}
}
}
impl From<crate::repository::RepositoryError> for SessionError {
fn from(value: crate::repository::RepositoryError) -> Self {
Self::Repository(value.into())
}
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum RevocationError {
#[error("cannot revoke missing session")]
SessionNotFound,
#[error("cannot revoke missing session family")]
SessionFamilyNotFound,
#[error("revocation failed")]
Failed,
}