1
use bonsaidb_core::{
2
    define_basic_mapped_view, define_basic_unique_mapped_view,
3
    document::{CollectionDocument, Emit, KeyId},
4
    schema::{Collection, NamedCollection, Schema},
5
};
6
use fabruic::{CertificateChain, PrivateKey};
7
use serde::{de::Visitor, Deserialize, Serialize};
8

            
9
3850
#[derive(Debug, Schema)]
10
#[schema(name = "hosted", authority = "khonsulabs", collections = [TlsCertificate], core = bonsaidb_core)]
11
#[cfg_attr(feature = "acme", schema(collections = [crate::server::acme::AcmeAccount]))]
12
pub struct Hosted;
13

            
14
14371
#[derive(Clone, Debug, Serialize, Deserialize, Collection)]
15
#[collection(name = "tls-certificates", authority = "khonsulabs", views = [TlsCertificatesByDomain, TlsCertificateByAllDomains])]
16
#[collection(encryption_key = Some(KeyId::Master), encryption_optional, core = bonsaidb_core)]
17
pub struct TlsCertificate {
18
    pub domains: Vec<String>,
19
    pub private_key: SerializablePrivateKey,
20
    pub certificate_chain: CertificateChain,
21
}
22

            
23
impl NamedCollection for TlsCertificate {
24
    type ByNameView = TlsCertificateByAllDomains;
25
}
26

            
27
define_basic_unique_mapped_view!(
28
    TlsCertificateByAllDomains,
29
    TlsCertificate,
30
    1,
31
    "by-all-domains",
32
    String,
33
593
    |document: CollectionDocument<TlsCertificate>| {
34
593
        document
35
593
            .header
36
593
            .emit_key(document.contents.domains.join(";"))
37
593
    }
38
);
39

            
40
define_basic_mapped_view!(
41
    TlsCertificatesByDomain,
42
    TlsCertificate,
43
    1,
44
    "by-domain",
45
    String,
46
    CertificateChain,
47
580
    |document: CollectionDocument<TlsCertificate>| {
48
580
        document
49
580
            .contents
50
580
            .domains
51
580
            .into_iter()
52
580
            .map(|domain| {
53
580
                document
54
580
                    .header
55
580
                    .emit_key_and_value(domain, document.contents.certificate_chain.clone())
56
580
            })
57
580
            .collect()
58
580
    }
59
);
60

            
61
#[derive(Clone, Debug)]
62
pub struct SerializablePrivateKey(pub PrivateKey);
63

            
64
impl Serialize for SerializablePrivateKey {
65
76
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66
76
    where
67
76
        S: serde::Serializer,
68
76
    {
69
76
        fabruic::dangerous::PrivateKey::serialize(&self.0, serializer)
70
76
    }
71
}
72

            
73
impl<'de> Deserialize<'de> for SerializablePrivateKey {
74
2053
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
75
2053
    where
76
2053
        D: serde::Deserializer<'de>,
77
2053
    {
78
2053
        PrivateKey::deserialize(deserializer).map(Self)
79
2053
    }
80
}
81

            
82
struct SerializablePrivateKeyVisitor;
83

            
84
impl<'de> Visitor<'de> for SerializablePrivateKeyVisitor {
85
    type Value = SerializablePrivateKey;
86

            
87
    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88
        formatter.write_str("byte array")
89
    }
90

            
91
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
92
    where
93
        E: serde::de::Error,
94
    {
95
        Ok(SerializablePrivateKey(PrivateKey::unchecked_from_der(
96
            v.to_vec(),
97
        )))
98
    }
99
}