JMAP Registry API implementation - part 10

This commit is contained in:
mdecimus
2026-03-06 19:50:10 +01:00
parent 9f9ddee965
commit d15efc6fb9
67 changed files with 2186 additions and 1879 deletions

View File

@@ -7,7 +7,7 @@
use crate::{
schema::{
enums::{TracingLevel, TracingLevelOpt},
prelude::{NodeRange, Object, ObjectInner, Property},
prelude::{Object, ObjectInner, Property},
},
types::EnumImpl,
};
@@ -28,12 +28,6 @@ pub mod structs;
#[allow(clippy::derivable_impls)]
pub mod structs_impl;
impl NodeRange {
pub fn contains(&self, node_id: u64) -> bool {
node_id >= self.from_node_id && node_id <= self.to_node_id
}
}
impl Display for Property {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())

View File

@@ -160,3 +160,9 @@ impl IntoValue for Duration {
JmapValue::Number((self.0.as_millis() as u64).into())
}
}
impl From<std::time::Duration> for Duration {
fn from(value: std::time::Duration) -> Self {
Duration(value)
}
}

View File

@@ -4,7 +4,11 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::{jmap::JsonPointerPatch, schema::prelude::Property, types::id::ObjectId};
use crate::{
jmap::JsonPointerPatch,
schema::prelude::Property,
types::{EnumImpl, id::ObjectId},
};
use std::{borrow::Cow, fmt::Display};
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
@@ -103,6 +107,58 @@ impl Warning {
message: message.to_string(),
}
}
pub fn log(&self) {
trc::event!(
Registry(trc::RegistryEvent::BuildWarning),
Source = self.object_id.object().as_str(),
Id = self.object_id.id().id(),
Key = self.property.map(|key| key.as_str()),
Reason = self.message.clone(),
);
}
}
impl Error {
pub fn log(&self) {
match self {
Error::Validation { object_id, errors } => {
trc::event!(
Registry(trc::RegistryEvent::ValidationError),
Source = object_id.object().as_str(),
Id = object_id.id().id(),
Reason = errors
.iter()
.map(|err| trc::Value::from(err.to_string()))
.collect::<Vec<_>>(),
);
}
Error::Build { object_id, message } => {
trc::event!(
Registry(trc::RegistryEvent::BuildError),
Source = object_id.object().as_str(),
Id = object_id.id().id(),
Reason = message.clone(),
);
}
Error::Internal { object_id, error } => {
trc::event!(
Registry(trc::RegistryEvent::ReadError),
Source = object_id.as_ref().map(|id| id.object().as_str()),
Id = object_id.as_ref().map(|id| id.id().id()),
CausedBy = error.clone(),
);
}
Error::NotFound { object_id } => {
trc::event!(
Registry(trc::RegistryEvent::BuildError),
Source = object_id.object().as_str(),
Id = object_id.id().id(),
Reason = "Object not found",
);
}
}
}
}
impl Display for ValidationError {

View File

@@ -4,7 +4,9 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::schema::prelude::Roles;
use std::borrow::Cow;
use crate::schema::prelude::{DkimPrivateKey, DkimSignature, Roles};
use types::id::Id;
pub mod account;
@@ -23,3 +25,30 @@ impl Roles {
}
}
}
impl DkimSignature {
pub fn private_key(&self) -> &DkimPrivateKey {
match self {
DkimSignature::Dkim1Ed25519Sha256(signature) => &signature.private_key,
DkimSignature::Dkim1RsaSha256(signature) => &signature.private_key,
}
}
pub fn private_key_mut(&mut self) -> &mut DkimPrivateKey {
match self {
DkimSignature::Dkim1Ed25519Sha256(signature) => &mut signature.private_key,
DkimSignature::Dkim1RsaSha256(signature) => &mut signature.private_key,
}
}
}
impl DkimPrivateKey {
pub async fn pem(&self) -> trc::Result<Cow<'_, str>> {
match self {
DkimPrivateKey::Value(value) => Ok(Cow::Borrowed(value.secret.as_str())),
DkimPrivateKey::File(file) => file.secret().await.map(Cow::Owned),
DkimPrivateKey::Generate => Err("Key is in invalid generate state".to_string()),
}
.map_err(|err| trc::DkimEvent::BuildError.reason(err))
}
}

View File

@@ -8,7 +8,10 @@ use crate::{
schema::{enums, prelude::UTCDateTime, structs},
types::{ipaddr::IpAddr, list::List},
};
use mail_auth::report::{tlsrpt::*, *};
use mail_auth::{
IprevOutput, IprevResult, SpfOutput,
report::{tlsrpt::*, *},
};
use std::borrow::Cow;
impl From<enums::DmarcAlignment> for Alignment {
@@ -802,3 +805,125 @@ fn fo_to_failure_reporting_options(fo: &Option<String>) -> Vec<enums::FailureRep
.collect(),
}
}
impl From<&SpfOutput> for structs::DmarcTroubleshootAuthResult {
fn from(value: &SpfOutput) -> Self {
match value.result() {
mail_auth::SpfResult::Pass => structs::DmarcTroubleshootAuthResult::Pass,
mail_auth::SpfResult::Fail => {
structs::DmarcTroubleshootAuthResult::Fail(structs::DmarcTroubleshootDetails {
details: value.explanation().map(|e| e.to_string()),
})
}
mail_auth::SpfResult::SoftFail => {
structs::DmarcTroubleshootAuthResult::SoftFail(structs::DmarcTroubleshootDetails {
details: value.explanation().map(|e| e.to_string()),
})
}
mail_auth::SpfResult::Neutral => {
structs::DmarcTroubleshootAuthResult::Neutral(structs::DmarcTroubleshootDetails {
details: value.explanation().map(|e| e.to_string()),
})
}
mail_auth::SpfResult::TempError => {
structs::DmarcTroubleshootAuthResult::TempError(structs::DmarcTroubleshootDetails {
details: value.explanation().map(|e| e.to_string()),
})
}
mail_auth::SpfResult::PermError => {
structs::DmarcTroubleshootAuthResult::PermError(structs::DmarcTroubleshootDetails {
details: value.explanation().map(|e| e.to_string()),
})
}
mail_auth::SpfResult::None => structs::DmarcTroubleshootAuthResult::None,
}
}
}
impl From<&IprevOutput> for structs::DmarcTroubleshootAuthResult {
fn from(value: &IprevOutput) -> Self {
match &value.result {
IprevResult::Pass => structs::DmarcTroubleshootAuthResult::Pass,
IprevResult::Fail(error) => {
structs::DmarcTroubleshootAuthResult::Fail(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
IprevResult::TempError(error) => {
structs::DmarcTroubleshootAuthResult::TempError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
IprevResult::PermError(error) => {
structs::DmarcTroubleshootAuthResult::PermError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
IprevResult::None => structs::DmarcTroubleshootAuthResult::None,
}
}
}
impl From<&mail_auth::DkimResult> for structs::DmarcTroubleshootAuthResult {
fn from(value: &mail_auth::DkimResult) -> Self {
match value {
mail_auth::DkimResult::Pass => structs::DmarcTroubleshootAuthResult::Pass,
mail_auth::DkimResult::Neutral(error) => {
structs::DmarcTroubleshootAuthResult::Neutral(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DkimResult::Fail(error) => {
structs::DmarcTroubleshootAuthResult::Fail(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DkimResult::PermError(error) => {
structs::DmarcTroubleshootAuthResult::PermError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DkimResult::TempError(error) => {
structs::DmarcTroubleshootAuthResult::TempError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DkimResult::None => structs::DmarcTroubleshootAuthResult::None,
}
}
}
impl From<&mail_auth::DmarcResult> for structs::DmarcTroubleshootAuthResult {
fn from(value: &mail_auth::DmarcResult) -> Self {
match value {
mail_auth::DmarcResult::Pass => structs::DmarcTroubleshootAuthResult::Pass,
mail_auth::DmarcResult::Fail(error) => {
structs::DmarcTroubleshootAuthResult::Fail(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DmarcResult::TempError(error) => {
structs::DmarcTroubleshootAuthResult::TempError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DmarcResult::PermError(error) => {
structs::DmarcTroubleshootAuthResult::PermError(structs::DmarcTroubleshootDetails {
details: error.to_string().into(),
})
}
mail_auth::DmarcResult::None => structs::DmarcTroubleshootAuthResult::None,
}
}
}
impl From<&mail_auth::dmarc::Policy> for enums::DmarcDisposition {
fn from(value: &mail_auth::dmarc::Policy) -> Self {
match value {
mail_auth::dmarc::Policy::None => enums::DmarcDisposition::None,
mail_auth::dmarc::Policy::Quarantine => enums::DmarcDisposition::Quarantine,
mail_auth::dmarc::Policy::Reject => enums::DmarcDisposition::Reject,
mail_auth::dmarc::Policy::Unspecified => enums::DmarcDisposition::Unspecified,
}
}
}