diff --git a/migrations/20230829165636_discovery.sql b/migrations/20230829165636_discovery.sql new file mode 100644 index 0000000..2c6b546 --- /dev/null +++ b/migrations/20230829165636_discovery.sql @@ -0,0 +1,13 @@ +CREATE TYPE discovery_type AS ENUM +( + 'instance', + 'repository' +); + +CREATE TABLE IF NOT EXISTS discoveries +( + discovery_hash TEXT PRIMARY KEY UNIQUE NOT NULL, + discovery_time TEXT NOT NULL, + discovery_type discovery_type NOT NULL, + discovery TEXT NOT NULL +); \ No newline at end of file diff --git a/src/authentication.rs b/src/authentication.rs index beaa3ef..0f0b5ff 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -32,9 +32,13 @@ impl AuthenticationTokenGranter { let _secret_key = self.config["authentication"]["secret_key"] .as_str() .unwrap(); - let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) - .await - .unwrap(); + let mut file = File::open( + self.config["giterated"]["keys"]["private"] + .as_str() + .unwrap(), + ) + .await + .unwrap(); let mut key = vec![]; file.read_to_end(&mut key).await.unwrap(); @@ -85,9 +89,13 @@ impl AuthenticationTokenGranter { .as_str() .unwrap(); let private_key = { - let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) - .await - .unwrap(); + let mut file = File::open( + self.config["giterated"]["keys"]["private"] + .as_str() + .unwrap(), + ) + .await + .unwrap(); let mut key = vec![]; file.read_to_end(&mut key).await.unwrap(); @@ -179,9 +187,13 @@ impl AuthenticationTokenGranter { info!("Validated request for key extension"); let private_key = { - let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) - .await - .unwrap(); + let mut file = File::open( + self.config["giterated"]["keys"]["private"] + .as_str() + .unwrap(), + ) + .await + .unwrap(); let mut key = vec![]; file.read_to_end(&mut key).await.unwrap(); diff --git a/src/backend/discovery.rs b/src/backend/discovery.rs index 4a395f8..07566a8 100644 --- a/src/backend/discovery.rs +++ b/src/backend/discovery.rs @@ -8,7 +8,7 @@ pub struct GiteratedDiscoveryProtocol {} #[async_trait::async_trait] impl DiscoveryBackend for GiteratedDiscoveryProtocol { - async fn try_handle(&mut self, request: DiscoveryMessage) -> Result { + async fn try_handle(&mut self, request: &DiscoveryMessage) -> Result { todo!() } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 0d71899..40ed8c4 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -89,6 +89,6 @@ pub trait UserBackend: AuthBackend { #[async_trait::async_trait] pub trait DiscoveryBackend { - async fn try_handle(&mut self, request: DiscoveryMessage) -> Result; + async fn try_handle(&mut self, request: &DiscoveryMessage) -> Result; async fn search(&mut self, search: &str) -> Result, Error>; } diff --git a/src/connection.rs b/src/connection.rs index ce63554..df69dcf 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -15,7 +15,7 @@ use tokio_tungstenite::{tungstenite::Message, WebSocketStream}; use crate::{ authentication::AuthenticationTokenGranter, - backend::{IssuesBackend, RepositoryBackend, UserBackend}, + backend::{DiscoveryBackend, IssuesBackend, RepositoryBackend, UserBackend}, handshake::{HandshakeFinalize, HandshakeMessage, HandshakeResponse}, listener::Listeners, messages::{ @@ -63,6 +63,7 @@ pub async fn connection_worker( backend: Arc>, user_backend: Arc>, auth_granter: Arc>, + discovery_backend: Arc>, addr: SocketAddr, ) { let mut handshaked = false; @@ -409,6 +410,13 @@ pub async fn connection_worker( AuthenticationMessage::Response(_) => unreachable!(), } } + + if let MessageKind::Discovery(message) = &message { + let mut backend = discovery_backend.lock().await; + backend.try_handle(message).await.unwrap(); + + continue; + } } info!("Connection closed"); @@ -426,6 +434,7 @@ async fn send_and_get_listener( } MessageKind::Repository(repository) => (None, None, Some(repository.target.clone())), MessageKind::Authentication(_) => todo!(), + MessageKind::Discovery(_) => todo!(), }; let target = match (&instance, &user, &repository) { diff --git a/src/main.rs b/src/main.rs index 5963c41..d7750ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,10 @@ use anyhow::Error; use connection::{connection_worker, Connections, RawConnection}; use giterated_daemon::{ authentication::AuthenticationTokenGranter, - backend::{git::GitBackend, user::UserAuth, RepositoryBackend, UserBackend}, + backend::{ + discovery::GiteratedDiscoveryProtocol, git::GitBackend, user::UserAuth, DiscoveryBackend, + RepositoryBackend, UserBackend, + }, connection, listener, model::instance::Instance, }; @@ -50,7 +53,7 @@ async fn main() -> Result<(), Error> { let foo: GitBackend = GitBackend { pg_pool: db_pool.clone(), repository_folder: String::from( - config["repository"]["backend"]["git"]["root"] + config["giterated"]["backend"]["git"]["root"] .as_str() .unwrap(), ), @@ -68,6 +71,9 @@ async fn main() -> Result<(), Error> { token_granter.clone(), ))); + let discovery_backend: Arc> = + Arc::new(Mutex::new(GiteratedDiscoveryProtocol {})); + info!("Connected"); loop { @@ -107,6 +113,7 @@ async fn main() -> Result<(), Error> { repository_backend.clone(), user_backend.clone(), token_granter.clone(), + discovery_backend.clone(), address, )), }; diff --git a/src/messages/discovery.rs b/src/messages/discovery.rs index a94df28..43534f4 100644 --- a/src/messages/discovery.rs +++ b/src/messages/discovery.rs @@ -5,31 +5,31 @@ use crate::model::discovery::DiscoveryItem; use super::InstanceAuthenticated; -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct DiscoveryMessage { pub message: InstanceAuthenticated, } -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub enum DiscoveryMessageKind { Offer(DiscoveryOffer), Request(DiscoveryRequest), Discoveries(Discoveries), } -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct DiscoveryOffer { pub earliest: DateTime, pub hashes: Vec, } -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct DiscoveryRequest { pub since: DateTime, pub hashes: Vec, } -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct Discoveries { pub discoveries: Vec, } diff --git a/src/messages/mod.rs b/src/messages/mod.rs index 673a2d9..be40dcb 100644 --- a/src/messages/mod.rs +++ b/src/messages/mod.rs @@ -16,7 +16,10 @@ use crate::{ model::{instance::Instance, user::User}, }; -use self::{authentication::AuthenticationMessage, repository::RepositoryMessage}; +use self::{ + authentication::AuthenticationMessage, discovery::DiscoveryMessage, + repository::RepositoryMessage, +}; pub mod authentication; pub mod discovery; @@ -29,6 +32,7 @@ pub enum MessageKind { Handshake(HandshakeMessage), Repository(RepositoryMessage), Authentication(AuthenticationMessage), + Discovery(DiscoveryMessage), } /// An authenticated message, where the instance is authenticating diff --git a/src/model/discovery.rs b/src/model/discovery.rs index b29e034..c49db64 100644 --- a/src/model/discovery.rs +++ b/src/model/discovery.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::model::{instance::Instance, repository::Repository}; -#[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub enum DiscoveryItem { Instance { instance: Instance, diff --git a/src/model/instance.rs b/src/model/instance.rs index 5197c63..45e0b20 100644 --- a/src/model/instance.rs +++ b/src/model/instance.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; +use thiserror::Error; pub struct InstanceMeta { pub url: String, @@ -36,9 +37,15 @@ impl ToString for Instance { } impl FromStr for Instance { - type Err = (); + type Err = InstanceParseError; fn from_str(s: &str) -> Result { Ok(Self { url: s.to_string() }) } } + +#[derive(Debug, Error)] +pub enum InstanceParseError { + #[error("invalid format")] + InvalidFormat, +}