use std::array::TryFromSliceError;
#[cfg(feature = "non-fips")]
use cloudproof_findex::implementations::redis::FindexRedisError;
use cosmian_kmip::{
KmipError, kmip_0::kmip_types::ErrorReason, kmip_1_4::kmip_types::ResultReason,
};
use cosmian_kms_crypto::{CryptoError, reexport::cosmian_crypto_core::CryptoCoreError};
use cosmian_kms_interfaces::InterfaceError;
use redis::ErrorKind;
use thiserror::Error;
use crate::DbError::CryptographicError;
#[derive(Error, Debug, Clone)]
pub enum DbError {
#[error("Certificate error: {0}")]
Certificate(String),
#[error("REST client connection error: {0}")]
ClientConnectionError(String),
#[error("Conversion Error: {0}")]
ConversionError(String),
#[error("Cryptographic error: {0}")]
CryptographicError(String),
#[error("Database Error: {0}")]
DatabaseError(String),
#[error("{0}")]
Default(String),
#[error("Findex Error: {0}")]
Findex(String),
#[error("Inconsistent operation: {0}")]
InconsistentOperation(String),
#[error("Invalid Request: {0}")]
InvalidRequest(String),
#[error("Item not found: {0}")]
ItemNotFound(String),
#[error("{0}: {1}")]
Kmip14Error(ResultReason, String),
#[error("{0}: {1}")]
Kmip21Error(ErrorReason, String),
#[error("Not Supported: {0}")]
NotSupported(String),
#[error("Proteccio error: {0}")]
Proteccio(String),
#[error("Redis Error: {0}")]
Redis(String),
#[error("Route not supported: {0}")]
RouteNotFound(String),
#[error("Unexpected server error: {0}")]
ServerError(String),
#[error("Ext. store error: {0}")]
Store(String),
#[error("Access denied: {0}")]
Unauthorized(String),
#[error("This KMIP server does not yet support place holder id")]
UnsupportedPlaceholder,
#[error("This KMIP server does not yet support protection masks")]
UnsupportedProtectionMasks,
#[error("Invalid URL: {0}")]
UrlError(String),
}
impl From<std::string::FromUtf8Error> for DbError {
fn from(e: std::string::FromUtf8Error) -> Self {
Self::ConversionError(e.to_string())
}
}
impl From<std::num::TryFromIntError> for DbError {
fn from(e: std::num::TryFromIntError) -> Self {
Self::ConversionError(e.to_string())
}
}
impl From<sqlx::Error> for DbError {
fn from(e: sqlx::Error) -> Self {
Self::DatabaseError(e.to_string())
}
}
impl From<std::io::Error> for DbError {
fn from(e: std::io::Error) -> Self {
Self::ServerError(e.to_string())
}
}
impl From<serde_json::Error> for DbError {
fn from(e: serde_json::Error) -> Self {
Self::InvalidRequest(e.to_string())
}
}
impl From<TryFromSliceError> for DbError {
fn from(e: TryFromSliceError) -> Self {
Self::ConversionError(e.to_string())
}
}
impl From<redis::RedisError> for DbError {
fn from(err: redis::RedisError) -> Self {
Self::Redis(err.to_string())
}
}
impl From<DbError> for redis::RedisError {
fn from(val: DbError) -> Self {
Self::from((ErrorKind::ClientError, "KMS Error", val.to_string()))
}
}
impl From<tracing::dispatcher::SetGlobalDefaultError> for DbError {
fn from(e: tracing::dispatcher::SetGlobalDefaultError) -> Self {
Self::ServerError(e.to_string())
}
}
impl From<InterfaceError> for DbError {
fn from(value: InterfaceError) -> Self {
match value {
InterfaceError::Db(s) => Self::Store(s),
x => Self::Store(x.to_string()),
}
}
}
impl From<CryptoCoreError> for DbError {
fn from(e: CryptoCoreError) -> Self {
CryptographicError(e.to_string())
}
}
impl From<CryptoError> for DbError {
fn from(e: CryptoError) -> Self {
match e {
CryptoError::Kmip(s) => Self::Kmip21Error(ErrorReason::Codec_Error, s),
CryptoError::InvalidSize(s)
| CryptoError::InvalidTag(s)
| CryptoError::Derivation(s)
| CryptoError::IndexingSlicing(s) => Self::InvalidRequest(s),
CryptoError::ObjectNotFound(s) => Self::ItemNotFound(s),
CryptoError::ConversionError(e)
| CryptoError::Default(e)
| CryptoError::NotSupported(e)
| CryptoError::OpenSSL(e) => CryptographicError(e),
CryptoError::Io(e) => CryptographicError(e.to_string()),
CryptoError::SerdeJsonError(e) => CryptographicError(e.to_string()),
#[cfg(feature = "non-fips")]
CryptoError::Covercrypt(e) => CryptographicError(e.to_string()),
CryptoError::TryFromSliceError(e) => CryptographicError(e.to_string()),
}
}
}
#[cfg(feature = "non-fips")]
impl From<FindexRedisError> for DbError {
fn from(e: FindexRedisError) -> Self {
Self::Findex(e.to_string())
}
}
impl From<KmipError> for DbError {
fn from(e: KmipError) -> Self {
match e {
KmipError::InvalidKmip21Value(r, s)
| KmipError::InvalidKmip21Object(r, s)
| KmipError::Kmip21(r, s) => Self::Kmip21Error(r, s),
KmipError::Kmip21NotSupported(_, s)
| KmipError::NotSupported(s)
| KmipError::Default(s)
| KmipError::InvalidSize(s)
| KmipError::InvalidTag(s)
| KmipError::Derivation(s)
| KmipError::ConversionError(s)
| KmipError::IndexingSlicing(s)
| KmipError::ObjectNotFound(s) => Self::NotSupported(s),
KmipError::TryFromSliceError(s) => Self::ConversionError(s.to_string()),
KmipError::SerdeJsonError(s) => Self::ConversionError(s.to_string()),
KmipError::Deserialization(e) | KmipError::Serialization(e) => {
Self::Kmip21Error(ErrorReason::Codec_Error, e)
}
KmipError::DeserializationSize(expected, actual) => Self::Kmip21Error(
ErrorReason::Codec_Error,
format!("Deserialization: invalid size: {actual}, expected: {expected}"),
),
KmipError::InvalidKmip14Value(result_reason, e)
| KmipError::InvalidKmip14Object(result_reason, e)
| KmipError::Kmip14(result_reason, e) => Self::Kmip14Error(result_reason, e),
}
}
}
impl From<DbError> for InterfaceError {
fn from(value: DbError) -> Self {
Self::Db(value.to_string())
}
}