Skip to content

Commit 3b7fe7d

Browse files
committed
wip: fix some server-side compile errors
1 parent 499c2f4 commit 3b7fe7d

File tree

10 files changed

+110
-85
lines changed

10 files changed

+110
-85
lines changed

sandpolis-database/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,11 +824,14 @@ impl DataCondition {
824824
}
825825
}
826826

827-
fn equal(key: impl ToKeyDefinition<KeyOptions>, value: impl ToKey) -> Self {
827+
pub fn equal(key: impl ToKeyDefinition<KeyOptions>, value: impl ToKey) -> Self {
828828
Self::Equal(key.key_definition(), value.to_key())
829829
}
830830

831-
fn range<R: RangeBounds<impl ToKey>>(key: impl ToKeyDefinition<KeyOptions>, value: R) -> Self {
831+
pub fn range<R: RangeBounds<impl ToKey>>(
832+
key: impl ToKeyDefinition<KeyOptions>,
833+
value: R,
834+
) -> Self {
832835
Self::Range(key.key_definition(), KeyRange::new(value))
833836
}
834837
}

sandpolis-filesystem/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ sandpolis-core = { path = "../sandpolis-core", version = "0.0.1" }
1919

2020
[features]
2121
agent = ["dep:notify"]
22-
client = ["dep:fuser"]
22+
client = [
23+
#"dep:fuser"
24+
]
2325
client-gui = ["client"]
2426
client-tui = ["client"]
2527
server = []

sandpolis-realm/src/lib.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use native_model::Model;
1111
use pem::Pem;
1212
use pem::encode;
1313
use sandpolis_core::{RealmName, UserName};
14+
use sandpolis_database::RealmDatabase;
1415
use sandpolis_database::ResidentVec;
1516
use sandpolis_database::{DatabaseLayer, Resident};
1617
use sandpolis_instance::InstanceLayer;
@@ -35,8 +36,9 @@ pub struct RealmLayerData {
3536

3637
#[derive(Clone)]
3738
pub struct RealmLayer {
39+
database: DatabaseLayer,
3840
data: Resident<RealmLayerData>,
39-
realms: ResidentVec<RealmData>,
41+
pub realms: ResidentVec<RealmData>,
4042
}
4143

4244
impl RealmLayer {
@@ -53,16 +55,15 @@ impl RealmLayer {
5355

5456
#[cfg(feature = "server")]
5557
{
56-
let cluster_cert = RealmClusterCert::new(
57-
instance_layer.data.value().cluster_id,
58-
RealmName::default(),
59-
)?;
60-
let server_cert = cluster_cert.server_cert(instance_layer.data.value().instance_id)?;
61-
62-
let rw = realm_db.rw_transaction()?;
63-
rw.insert(cluster_cert)?;
64-
rw.insert(server_cert)?;
65-
rw.commit()?;
58+
// let cluster_cert =
59+
// RealmClusterCert::new(instance.data.value().cluster_id,
60+
// RealmName::default())?; let server_cert =
61+
// cluster_cert.server_cert(instance.data.value().instance_id)?;
62+
63+
// let rw = realm_db.rw_transaction()?;
64+
// rw.insert(cluster_cert)?;
65+
// rw.insert(server_cert)?;
66+
// rw.commit()?;
6667
}
6768

6869
// Update client cert if possible
@@ -82,10 +83,21 @@ impl RealmLayer {
8283
// }
8384

8485
Ok(Self {
86+
database,
8587
data: default_realm.resident(())?,
8688
realms,
8789
})
8890
}
91+
92+
pub async fn realm(&self, name: RealmName) -> Result<RealmDatabase> {
93+
// Don't allow this method to create realms that don't already exist
94+
for realm in self.realms.iter().await {
95+
if realm.read().await.name == name {
96+
return Ok(self.database.realm(name).await?);
97+
}
98+
}
99+
bail!("Realm does not exist");
100+
}
89101
}
90102

91103
/// A realm is a set of clients and agents that can interact. Each realm has a
@@ -110,7 +122,7 @@ pub struct RealmClusterCert {
110122
}
111123

112124
/// Each server in the cluster gets its own server certificate.
113-
#[data]
125+
#[data(instance)]
114126
pub struct RealmServerCert {
115127
pub cert: Vec<u8>,
116128
pub key: Option<Vec<u8>>,
@@ -250,17 +262,17 @@ impl RealmClientCert {
250262

251263
#[cfg(test)]
252264
mod test_client_cert {
253-
use super::RealmClientCert;
265+
use super::*;
254266

255267
#[test]
256268
fn test_read_write() -> Result<()> {
257269
let mut temp_file = tempfile::NamedTempFile::new()?;
258270

259271
let cert = RealmClientCert {
260-
ca: "doesn't have to be a valid cert".bytes(),
261-
cert: "doesn't have to be a valid cert".bytes(),
262-
key: Some("doesn't have to be a valid key".bytes()),
263-
_id: 0,
272+
ca: "doesn't have to be a valid cert".as_bytes().to_vec(),
273+
cert: "doesn't have to be a valid cert".as_bytes().to_vec(),
274+
key: Some("doesn't have to be a valid key".as_bytes().to_vec()),
275+
..Default::default()
264276
};
265277

266278
cert.write(temp_file.path())?;

sandpolis-realm/src/server.rs

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use crate::RealmLayer;
2+
use crate::RealmServerCertKey;
3+
14
use super::RealmClientCert;
25
use super::RealmClusterCert;
36
use super::RealmData;
@@ -31,16 +34,18 @@ use rustls_pki_types::pem::PemObject;
3134
use sandpolis_core::ClusterId;
3235
use sandpolis_core::InstanceId;
3336
use sandpolis_core::InstanceType;
37+
use sandpolis_database::DataCondition;
38+
use sandpolis_database::Resident;
39+
use sandpolis_instance::InstanceLayer;
3440
use std::io;
3541
use std::sync::Arc;
36-
use tempfile::TempDir;
37-
use tempfile::tempdir;
3842
use time::Duration;
3943
use time::OffsetDateTime;
4044
use tokio::io::{AsyncRead, AsyncWrite};
4145
use tokio_rustls::server::TlsStream;
4246
use tower::Layer;
4347
use tracing::debug;
48+
use tracing::trace;
4449
use x509_parser::prelude::{FromDer, X509Certificate};
4550

4651
impl super::RealmClusterCert {
@@ -225,44 +230,46 @@ pub struct TlsData {
225230
pub struct RealmAcceptor(RustlsAcceptor);
226231

227232
impl RealmAcceptor {
228-
pub fn new(realms: Vec<RealmData>) -> Result<Self> {
233+
pub async fn new(instance_layer: InstanceLayer, realm_layer: RealmLayer) -> Result<Self> {
229234
let mut roots = RootCertStore::empty();
230235
let mut sni_resolver = ResolvesServerCertUsingSni::new();
231236

232237
let config = ServerConfig::builder();
233238

234-
for realm in realms {
239+
for realm in realm_layer.realms.iter().await {
240+
let realm = realm.read().await;
241+
let db = realm_layer.realm(realm.name.clone()).await?;
242+
trace!(name = *realm.name, "Registering realm with server acceptor");
243+
235244
// Add cluster cert as a CA cert to the root store
236245
{
237-
let cluster_cert: &RealmClusterCert = realm
238-
.cluster_cert
239-
.as_ref()
240-
.ok_or_else(|| anyhow!("No cluster cert")?);
246+
let cluster_cert: Resident<RealmClusterCert> = db.resident(())?;
241247

242-
roots.add(pem::parse(&cluster_cert.cert)?.into_contents().try_into()?)?;
248+
roots.add(cluster_cert.read().await.cert.clone().try_into()?)?;
243249
}
244250

245251
// Add server cert to the SNI resolver
246252
{
247-
let server_cert: Document<RealmServerCert> = realm.get_document("server")?.unwrap();
253+
let server_cert: Resident<RealmServerCert> = db.resident(DataCondition::equal(
254+
RealmServerCertKey::_instance_id,
255+
instance_layer.instance_id,
256+
))?;
257+
248258
let private_key = config.crypto_provider().key_provider.load_private_key(
249-
PrivateKeyDer::from_pem_slice(
250-
&server_cert
251-
.data
252-
.key
253-
.ok_or_else(|| anyhow!("No server key")?)
254-
.as_bytes(),
255-
)?,
259+
server_cert
260+
.read()
261+
.await
262+
.key
263+
.clone()
264+
.ok_or_else(|| anyhow!("No server key"))?
265+
.try_into()
266+
.map_err(|_| anyhow!("Failed to parse key"))?,
256267
)?;
257268

258269
sni_resolver.add(
259-
&server_cert.data.subject_name()?,
270+
&server_cert.read().await.subject_name()?,
260271
rustls::sign::CertifiedKey::new(
261-
vec![
262-
pem::parse(&server_cert.data.cert)?
263-
.into_contents()
264-
.try_into()?,
265-
],
272+
vec![server_cert.read().await.cert.clone().try_into()?],
266273
private_key,
267274
),
268275
)?;

sandpolis-server/src/lib.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use anyhow::Result;
22
use native_db::ToKey;
33
use native_model::Model;
4+
#[cfg(feature = "server")]
5+
use sandpolis_core::RealmName;
46
use sandpolis_core::{ClusterId, InstanceId};
57
use sandpolis_database::DatabaseLayer;
8+
use sandpolis_database::Resident;
69
use sandpolis_macros::data;
710
use sandpolis_network::NetworkLayer;
811
use serde::{Deserialize, Serialize};
@@ -28,18 +31,10 @@ pub struct ServerLayer {
2831
}
2932

3033
impl ServerLayer {
31-
pub fn new(database: DatabaseLayer, network: NetworkLayer) -> Result<Self> {
34+
pub async fn new(database: DatabaseLayer, network: NetworkLayer) -> Result<Self> {
3235
Ok(Self {
3336
#[cfg(feature = "server")]
34-
banner: if let Some(document) = data.get_document("/banner")? {
35-
document
36-
} else {
37-
// Load banner from another server if there is one
38-
// TODO
39-
40-
// Create a new banner
41-
data.document("/banner")?
42-
},
37+
banner: database.realm(RealmName::default()).await?.resident(())?,
4338
network,
4439
})
4540
}
@@ -50,7 +45,7 @@ impl ServerLayer {
5045
}
5146

5247
/// Contains information about the server useful for prospective logins
53-
#[derive(Serialize, Deserialize, Clone, Default)]
48+
#[data]
5449
pub struct ServerBannerData {
5550
pub cluster_id: ClusterId,
5651

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1+
use crate::ServerLayer;
12
use crate::messages::GetBannerRequest;
23
use crate::messages::GetBannerResponse;
3-
use crate::ServerLayer;
44
use axum::extract;
5-
use axum::{
6-
extract::State,
7-
routing::{get, post},
8-
Json, Router,
9-
};
5+
use axum::{Json, Router, extract::State};
106
use sandpolis_network::RequestResult;
117

128
/// Return a "banner" containing server metadata.
@@ -15,5 +11,7 @@ pub async fn banner(
1511
state: State<ServerLayer>,
1612
extract::Json(_): extract::Json<GetBannerRequest>,
1713
) -> RequestResult<GetBannerResponse> {
18-
Ok(Json(GetBannerResponse::Ok(state.banner.data.clone())))
14+
Ok(Json(GetBannerResponse::Ok(
15+
state.banner.read().await.clone(),
16+
)))
1917
}

sandpolis-user/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use anyhow::Result;
66
use native_db::ToKey;
77
use native_model::Model;
88
use sandpolis_core::UserName;
9+
use sandpolis_database::ResidentVec;
910
use sandpolis_database::{Data, DatabaseLayer};
1011
use sandpolis_macros::data;
1112
use serde::{Deserialize, Serialize};
@@ -27,14 +28,17 @@ pub struct UserLayerData {}
2728
pub struct UserLayer {
2829
pub database: DatabaseLayer,
2930
#[cfg(feature = "server")]
30-
pub users: DataView<UserData>,
31+
pub users: ResidentVec<UserData>,
3132
}
3233

3334
impl UserLayer {
34-
pub fn new(database: DatabaseLayer) -> Result<Self> {
35+
pub async fn new(database: DatabaseLayer) -> Result<Self> {
3536
Ok(Self {
3637
#[cfg(feature = "server")]
37-
users: data.collection("/users")?,
38+
users: database
39+
.realm(RealmName::default())
40+
.await?
41+
.resident_vec(())?,
3842
database,
3943
})
4044
}
Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use anyhow::Result;
22
use sandpolis::{client::tui::server_list::ServerListWidget, server::test_server};
33
use sandpolis_database::TemporaryDatabase;
4-
use sandpolis_realm::{RealmLayer, config::RealmConfig};
54
use sandpolis_instance::{InstanceId, InstanceLayer};
65
use sandpolis_network::{NetworkLayer, config::NetworkLayerConfig};
6+
use sandpolis_realm::{RealmLayer, config::RealmConfig};
77
use sandpolis_server::ServerLayer;
88
use std::sync::Arc;
99

@@ -12,25 +12,28 @@ async fn main() -> Result<()> {
1212
let test_server = test_server().await?;
1313

1414
let temp_db = TemporaryDatabase::new()?;
15-
let widget = ServerListWidget::new(ServerLayer::new(
16-
temp_db.db.document("/server")?,
17-
NetworkLayer::new(
18-
NetworkLayerConfig {
19-
servers: Some(vec![
20-
format!("127.0.0.1:{}", test_server.port).parse().unwrap(),
21-
]),
22-
poll: None,
23-
},
24-
temp_db.db.document("/network")?,
25-
RealmLayer::new(
26-
RealmConfig {
27-
certificate: Some(test_server.endpoint_cert),
15+
let widget = ServerListWidget::new(
16+
ServerLayer::new(
17+
temp_db.db.document("/server")?,
18+
NetworkLayer::new(
19+
NetworkLayerConfig {
20+
servers: Some(vec![
21+
format!("127.0.0.1:{}", test_server.port).parse().unwrap(),
22+
]),
23+
poll: None,
2824
},
29-
temp_db.db.document("/realm")?,
30-
InstanceLayer::new(temp_db.db.document("/instance")?)?,
25+
temp_db.db.document("/network")?,
26+
RealmLayer::new(
27+
RealmConfig {
28+
certificate: Some(test_server.endpoint_cert),
29+
},
30+
temp_db.db.document("/realm")?,
31+
InstanceLayer::new(temp_db.db.document("/instance")?)?,
32+
)?,
3133
)?,
32-
)?,
33-
)?);
34+
)
35+
.await?,
36+
);
3437
sandpolis_client::tui::test_widget(widget).await.unwrap();
3538
Ok(())
3639
}

sandpolis/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ impl InstanceState {
6767
sandpolis_network::NetworkLayer::new(config.network, database.clone(), realm.clone())
6868
.await?;
6969

70-
let user = sandpolis_user::UserLayer::new(database.clone())?;
70+
let user = sandpolis_user::UserLayer::new(database.clone()).await?;
7171

7272
let agent = sandpolis_agent::AgentLayer::new(database.clone()).await?;
7373

74-
let server = sandpolis_server::ServerLayer::new(database.clone(), network.clone())?;
74+
let server = sandpolis_server::ServerLayer::new(database.clone(), network.clone()).await?;
7575

7676
#[cfg(feature = "layer-package")]
7777
let package = sandpolis_package::PackageLayer::new().await?;

sandpolis/src/server/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ pub async fn main(config: Configuration, state: InstanceState) -> Result<()> {
4040
info!(listener = ?config.server.listen, "Starting server listener");
4141
axum_server::bind(config.server.listen)
4242
.acceptor(sandpolis_realm::server::RealmAcceptor::new(
43-
state.realm.realms.clone(),
43+
state.instance.clone(),
44+
state.realm.clone(),
4445
)?)
4546
.serve(app.with_state(state).into_make_service())
4647
.await

0 commit comments

Comments
 (0)