1
use bonsaidb_core::{
2
    define_basic_mapped_view, define_basic_unique_mapped_view,
3
    document::{CollectionDocument, KeyId},
4
    schema::{
5
        Collection, CollectionName, DefaultSerialization, NamedCollection, Schema, SchemaName,
6
        Schematic,
7
    },
8
    ENCRYPTION_ENABLED,
9
};
10
use fabruic::{CertificateChain, PrivateKey};
11
use serde::{de::Visitor, Deserialize, Serialize};
12

            
13
#[derive(Debug)]
14
pub struct Hosted;
15

            
16
impl Schema for Hosted {
17
8366
    fn schema_name() -> SchemaName {
18
8366
        SchemaName::new("khonsulabs", "hosted")
19
8366
    }
20

            
21
    fn define_collections(schema: &mut Schematic) -> Result<(), bonsaidb_core::Error> {
22
3800
        schema.define_collection::<TlsCertificate>()?;
23
        #[cfg(feature = "acme")]
24
3800
        schema.define_collection::<crate::server::acme::AcmeAccount>()?;
25
3802
        Ok(())
26
3802
    }
27
}
28

            
29
17101
#[derive(Debug, Serialize, Deserialize)]
30
pub struct TlsCertificate {
31
    pub domains: Vec<String>,
32
    pub private_key: SerializablePrivateKey,
33
    pub certificate_chain: CertificateChain,
34
}
35

            
36
impl NamedCollection for TlsCertificate {
37
    type ByNameView = TlsCertificateByAllDomains;
38
}
39

            
40
impl Collection for TlsCertificate {
41
3801
    fn encryption_key() -> Option<KeyId> {
42
3801
        if ENCRYPTION_ENABLED {
43
3801
            Some(KeyId::Master)
44
        } else {
45
            None
46
        }
47
3801
    }
48

            
49
46035
    fn collection_name() -> CollectionName {
50
46035
        CollectionName::new("khonsulabs", "tls-certificates")
51
46035
    }
52

            
53
    fn define_views(schema: &mut Schematic) -> Result<(), bonsaidb_core::Error> {
54
3801
        schema.define_view(TlsCertificatesByDomain)?;
55
3801
        schema.define_view(TlsCertificateByAllDomains)?;
56
3802
        Ok(())
57
3802
    }
58
}
59

            
60
impl DefaultSerialization for TlsCertificate {}
61

            
62
define_basic_unique_mapped_view!(
63
    TlsCertificateByAllDomains,
64
    TlsCertificate,
65
    1,
66
    "by-all-domains",
67
    String,
68
678
    |document: CollectionDocument<TlsCertificate>| {
69
678
        document.emit_key(document.contents.domains.join(";"))
70
678
    }
71
);
72

            
73
define_basic_mapped_view!(
74
    TlsCertificatesByDomain,
75
    TlsCertificate,
76
    1,
77
    "by-domain",
78
    String,
79
    CertificateChain,
80
712
    |document: CollectionDocument<TlsCertificate>| {
81
712
        document
82
712
            .contents
83
712
            .domains
84
712
            .into_iter()
85
712
            .map(|domain| {
86
712
                document
87
712
                    .header
88
712
                    .emit_key_and_value(domain, document.contents.certificate_chain.clone())
89
712
            })
90
712
            .collect()
91
712
    }
92
);
93

            
94
#[derive(Debug)]
95
pub struct SerializablePrivateKey(pub PrivateKey);
96

            
97
impl Serialize for SerializablePrivateKey {
98
69
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
99
69
    where
100
69
        S: serde::Serializer,
101
69
    {
102
69
        fabruic::dangerous::PrivateKey::serialize(&self.0, serializer)
103
69
    }
104
}
105

            
106
impl<'de> Deserialize<'de> for SerializablePrivateKey {
107
2443
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108
2443
    where
109
2443
        D: serde::Deserializer<'de>,
110
2443
    {
111
2443
        PrivateKey::deserialize(deserializer).map(Self)
112
2443
    }
113
}
114

            
115
struct SerializablePrivateKeyVisitor;
116

            
117
impl<'de> Visitor<'de> for SerializablePrivateKeyVisitor {
118
    type Value = SerializablePrivateKey;
119

            
120
    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121
        formatter.write_str("byte array")
122
    }
123

            
124
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
125
    where
126
        E: serde::de::Error,
127
    {
128
        Ok(SerializablePrivateKey(PrivateKey::unchecked_from_der(
129
            v.to_vec(),
130
        )))
131
    }
132
}