use thiserror::Error;
pub type SaTokenResult<T> = Result<T, SaTokenError>;
#[derive(Debug, Error)]
pub enum SaTokenError {
#[error("Token not found or expired")]
TokenNotFound,
#[error("Token is invalid: {0}")]
InvalidToken(String),
#[error("Token has expired")]
TokenExpired,
#[error("User not logged in")]
NotLogin,
#[error("Token is inactive")]
TokenInactive,
#[error("Permission denied")]
PermissionDenied,
#[error("Permission denied: missing permission '{0}'")]
PermissionDeniedDetail(String),
#[error("Role denied: missing role '{0}'")]
RoleDenied(String),
#[error("Account is banned until {0}")]
AccountBanned(String),
#[error("Account is kicked out")]
AccountKickedOut,
#[error("Session not found")]
SessionNotFound,
#[error("Nonce has been used, possible replay attack detected")]
NonceAlreadyUsed,
#[error("Invalid nonce format")]
InvalidNonceFormat,
#[error("Nonce timestamp is invalid or expired")]
InvalidNonceTimestamp,
#[error("Refresh token not found or expired")]
RefreshTokenNotFound,
#[error("Invalid refresh token data")]
RefreshTokenInvalidData,
#[error("Missing login_id in refresh token")]
RefreshTokenMissingLoginId,
#[error("Invalid expire time format in refresh token")]
RefreshTokenInvalidExpireTime,
#[error("Token is empty")]
TokenEmpty,
#[error("Token is too short")]
TokenTooShort,
#[error("Login ID is not a valid number")]
LoginIdNotNumber,
#[error("OAuth2 client not found")]
OAuth2ClientNotFound,
#[error("Invalid client credentials")]
OAuth2InvalidCredentials,
#[error("Client ID mismatch")]
OAuth2ClientIdMismatch,
#[error("Redirect URI mismatch")]
OAuth2RedirectUriMismatch,
#[error("Authorization code not found or expired")]
OAuth2CodeNotFound,
#[error("Access token not found or expired")]
OAuth2AccessTokenNotFound,
#[error("Refresh token not found or expired")]
OAuth2RefreshTokenNotFound,
#[error("Invalid refresh token data")]
OAuth2InvalidRefreshToken,
#[error("Invalid scope data")]
OAuth2InvalidScope,
#[error("SSO ticket not found or invalid")]
InvalidTicket,
#[error("SSO ticket has expired")]
TicketExpired,
#[error("Service URL mismatch")]
ServiceMismatch,
#[error("SSO session not found")]
SsoSessionNotFound,
#[error("Storage error: {0}")]
StorageError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("Internal error: {0}")]
InternalError(String),
}
impl SaTokenError {
pub fn message(&self) -> String {
self.to_string()
}
pub fn is_auth_error(&self) -> bool {
matches!(
self,
Self::NotLogin
| Self::TokenNotFound
| Self::TokenExpired
| Self::TokenInactive
| Self::InvalidToken(_)
)
}
pub fn is_authz_error(&self) -> bool {
matches!(
self,
Self::PermissionDenied
| Self::PermissionDeniedDetail(_)
| Self::RoleDenied(_)
)
}
}
pub mod messages {
pub const INVALID_CREDENTIALS: &str = "Invalid username or password";
pub const LOGIN_FAILED: &str = "Login failed";
pub const AUTH_ERROR: &str = "Authentication error";
pub const PERMISSION_REQUIRED: &str = "Permission required";
pub const ROLE_REQUIRED: &str = "Role required";
}