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

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

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

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

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

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

            
60
#[derive(Debug)]
61
pub struct SerializablePrivateKey(pub PrivateKey);
62

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

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

            
81
struct SerializablePrivateKeyVisitor;
82

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

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

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