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

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

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

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

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

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

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

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

            
72
impl<'de> Deserialize<'de> for SerializablePrivateKey {
73
2439
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
74
2439
    where
75
2439
        D: serde::Deserializer<'de>,
76
2439
    {
77
2439
        PrivateKey::deserialize(deserializer).map(Self)
78
2439
    }
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
}