use thiserror::Error;
#[derive(Error, Debug)]
pub enum SecurityError {
#[error("Authentication failed: {0}")]
AuthenticationFailed(String),
#[error("Invalid credentials: {0}")]
InvalidCredentials(String),
#[error("User not found: {0}")]
UserNotFound(String),
#[error("Account disabled: {0}")]
Disabled(String),
#[error("Account expired: {0}")]
AccountExpired(String),
#[error("Account locked: {0}")]
Locked(String),
#[error("Credentials expired: {0}")]
CredentialsExpired(String),
#[error("Access denied: {0}")]
AccessDenied(String),
#[error("Insufficient permissions: required {required}, but has {has}")]
InsufficientPermissions {
required: String,
has: String,
},
#[error("Invalid token: {0}")]
InvalidToken(String),
#[error("Expired token: {0}")]
ExpiredToken(String),
#[error("Token error: {0}")]
TokenError(String),
#[error("Token expired: {0}")]
TokenExpired(String),
#[error("CSRF validation failed: {0}")]
CsrfValidationFailed(String),
#[error("JWT error: {0}")]
Jwt(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Security error: {0}")]
Other(String),
}
impl SecurityError {
pub fn io_error(msg: impl Into<String>) -> Self {
SecurityError::Other(msg.into())
}
pub fn authentication_error(msg: impl Into<String>) -> Self {
SecurityError::AuthenticationFailed(msg.into())
}
pub fn invalid_token(msg: impl Into<String>) -> Self {
SecurityError::InvalidToken(msg.into())
}
pub fn expired_token(msg: impl Into<String>) -> Self {
SecurityError::TokenExpired(msg.into())
}
}
pub type SecurityResult<T> = Result<T, SecurityError>;
#[derive(Error, Debug)]
#[error("Access denied: {message}")]
pub struct AccessDeniedException {
pub message: String,
}
impl AccessDeniedException {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
pub fn insufficient_permissions(required: &str, has: &str) -> Self {
Self {
message: format!("Insufficient permissions: required {}, but has {}", required, has),
}
}
}
#[derive(Error, Debug)]
#[error("Authentication failed: {message}")]
pub struct AuthenticationException {
pub message: String,
}
impl AuthenticationException {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
pub fn bad_credentials() -> Self {
Self {
message: "Bad credentials".to_string(),
}
}
}