1
use std::path::Path;
2

            
3
#[cfg(feature = "encryption")]
4
use bonsaidb_core::document::KeyId;
5
use bonsaidb_core::{permissions::Permissions, schema::Schema};
6
#[cfg(feature = "compression")]
7
use bonsaidb_local::config::Compression;
8
use bonsaidb_local::config::{Builder, KeyValuePersistence, StorageConfiguration};
9
#[cfg(feature = "encryption")]
10
use bonsaidb_local::vault::AnyVaultKeyStorage;
11

            
12
/// Configuration options for [`Server`](crate::Server)
13
#[derive(Debug, Clone)]
14
#[must_use]
15
#[non_exhaustive]
16
pub struct ServerConfiguration {
17
    /// The DNS name of the server.
18
    pub server_name: String,
19
    /// Number of sumultaneous requests a single client can have in flight at a
20
    /// time. Default value is 16. It is important to have this number be tuned
21
    /// relative to `request_workers` such that one client cannot overwhelm the
22
    /// entire queue.
23
    pub client_simultaneous_request_limit: usize,
24
    /// Number of simultaneous requests to be processed. Default value is 16.
25
    pub request_workers: usize,
26
    /// Configuration options for individual databases.
27
    pub storage: StorageConfiguration,
28
    /// The permissions granted to all connections to this server.
29
    pub default_permissions: DefaultPermissions,
30
    /// The permissions granted to authenticated connections to this server.
31
    pub authenticated_permissions: DefaultPermissions,
32
    /// The ACME settings for automatic TLS certificate management.
33
    #[cfg(feature = "acme")]
34
    pub acme: AcmeConfiguration,
35
}
36

            
37
impl ServerConfiguration {
38
    /// Sets [`Self::server_name`](Self#structfield.server_name) to `server_name` and returns self.
39
32
    pub fn server_name(mut self, server_name: impl Into<String>) -> Self {
40
32
        self.server_name = server_name.into();
41
32
        self
42
32
    }
43

            
44
    /// Sets [`Self::client_simultaneous_request_limit`](Self#structfield.client_simultaneous_request_limit) to `request_limit` and returns self.
45
    pub const fn client_simultaneous_request_limit(mut self, request_limit: usize) -> Self {
46
        self.client_simultaneous_request_limit = request_limit;
47
        self
48
    }
49

            
50
    /// Sets [`Self::request_workers`](Self#structfield.request_workers) to `workers` and returns self.
51
    pub const fn request_workers(mut self, workers: usize) -> Self {
52
        self.request_workers = workers;
53
        self
54
    }
55

            
56
    /// Sets [`Self::default_permissions`](Self#structfield.default_permissions) to `default_permissions` and returns self.
57
80
    pub fn default_permissions<P: Into<DefaultPermissions>>(
58
80
        mut self,
59
80
        default_permissions: P,
60
80
    ) -> Self {
61
80
        self.default_permissions = default_permissions.into();
62
80
        self
63
80
    }
64

            
65
    /// Sets [`Self::authenticated_permissions`](Self#structfield.authenticated_permissions) to `authenticated_permissions` and returns self.
66
2
    pub fn authenticated_permissions<P: Into<DefaultPermissions>>(
67
2
        mut self,
68
2
        authenticated_permissions: P,
69
2
    ) -> Self {
70
2
        self.authenticated_permissions = authenticated_permissions.into();
71
2
        self
72
2
    }
73

            
74
    /// Sets [`AcmeConfiguration::contact_email`] to `contact_email` and returns self.
75
    #[cfg(feature = "acme")]
76
    pub fn acme_contact_email(mut self, contact_email: impl Into<String>) -> Self {
77
        self.acme.contact_email = Some(contact_email.into());
78
        self
79
    }
80

            
81
    /// Sets [`AcmeConfiguration::directory`] to `directory` and returns self.
82
    #[cfg(feature = "acme")]
83
    pub fn acme_directory(mut self, directory: impl Into<String>) -> Self {
84
        self.acme.directory = directory.into();
85
        self
86
    }
87
}
88

            
89
impl Default for ServerConfiguration {
90
913
    fn default() -> Self {
91
913
        Self {
92
913
            server_name: String::from("bonsaidb"),
93
913
            client_simultaneous_request_limit: 16,
94
913
            // TODO this was arbitrarily picked, it probably should be higher,
95
913
            // but it also should probably be based on the cpu's capabilities
96
913
            request_workers: 16,
97
913
            storage: bonsaidb_local::config::StorageConfiguration::default(),
98
913
            default_permissions: DefaultPermissions::Permissions(Permissions::default()),
99
913
            authenticated_permissions: DefaultPermissions::Permissions(Permissions::default()),
100
913
            #[cfg(feature = "acme")]
101
913
            acme: AcmeConfiguration::default(),
102
913
        }
103
913
    }
104
}
105

            
106
#[cfg(feature = "acme")]
107
mod acme {
108
    /// The Automated Certificate Management Environment (ACME) configuration.
109
    #[derive(Debug, Clone)]
110
    pub struct AcmeConfiguration {
111
        /// The contact email to register with the ACME directory for the account.
112
        pub contact_email: Option<String>,
113
        /// The ACME directory to use for registration. The default is
114
        /// [`LETS_ENCRYPT_PRODUCTION_DIRECTORY`].
115
        pub directory: String,
116
    }
117

            
118
    impl Default for AcmeConfiguration {
119
912
        fn default() -> Self {
120
912
            Self {
121
912
                contact_email: None,
122
912
                directory: LETS_ENCRYPT_PRODUCTION_DIRECTORY.to_string(),
123
912
            }
124
912
        }
125
    }
126

            
127
    pub use async_acme::acme::{LETS_ENCRYPT_PRODUCTION_DIRECTORY, LETS_ENCRYPT_STAGING_DIRECTORY};
128
}
129

            
130
#[cfg(feature = "acme")]
131
pub use acme::*;
132

            
133
/// The default permissions to use for all connections to the server.
134
#[derive(Debug, Clone)]
135
pub enum DefaultPermissions {
136
    /// Allow all permissions. Do not use outside of completely trusted environments.
137
    AllowAll,
138
    /// A defined set of permissions.
139
    Permissions(Permissions),
140
}
141

            
142
impl From<DefaultPermissions> for Permissions {
143
1826
    fn from(permissions: DefaultPermissions) -> Self {
144
1826
        match permissions {
145
967
            DefaultPermissions::Permissions(permissions) => permissions,
146
859
            DefaultPermissions::AllowAll => Self::allow_all(),
147
        }
148
1826
    }
149
}
150

            
151
impl From<Permissions> for DefaultPermissions {
152
90
    fn from(permissions: Permissions) -> Self {
153
90
        Self::Permissions(permissions)
154
90
    }
155
}
156

            
157
impl Builder for ServerConfiguration {
158
    fn with_schema<S: Schema>(mut self) -> Result<Self, bonsaidb_local::Error> {
159
78
        self.storage.register_schema::<S>()?;
160
78
        Ok(self)
161
78
    }
162

            
163
80
    fn path<P: AsRef<Path>>(mut self, path: P) -> Self {
164
80
        self.storage.path = Some(path.as_ref().to_owned());
165
80
        self
166
80
    }
167

            
168
    fn memory_only(mut self) -> Self {
169
        self.storage.memory_only = true;
170
        self
171
    }
172

            
173
    fn unique_id(mut self, unique_id: u64) -> Self {
174
        self.storage.unique_id = Some(unique_id);
175
        self
176
    }
177

            
178
    #[cfg(feature = "encryption")]
179
    fn vault_key_storage<VaultKeyStorage: AnyVaultKeyStorage>(
180
        mut self,
181
        key_storage: VaultKeyStorage,
182
    ) -> Self {
183
        self.storage.vault_key_storage = Some(std::sync::Arc::new(key_storage));
184
        self
185
    }
186

            
187
    #[cfg(feature = "encryption")]
188
    fn default_encryption_key(mut self, key: KeyId) -> Self {
189
        self.storage.default_encryption_key = Some(key);
190
        self
191
    }
192

            
193
    #[cfg(feature = "compression")]
194
121
    fn default_compression(mut self, compression: Compression) -> Self {
195
121
        self.storage.default_compression = Some(compression);
196
121
        self
197
121
    }
198

            
199
    fn tasks_worker_count(mut self, worker_count: usize) -> Self {
200
        self.storage.workers.worker_count = worker_count;
201
        self
202
    }
203

            
204
    fn check_view_integrity_on_open(mut self, check: bool) -> Self {
205
        self.storage.views.check_integrity_on_open = check;
206
        self
207
    }
208

            
209
324
    fn key_value_persistence(mut self, persistence: KeyValuePersistence) -> Self {
210
324
        self.storage.key_value_persistence = persistence;
211
324
        self
212
324
    }
213
}