woo
parent: tbd commit: 2d48bc0
Showing 10 changed files with 74 insertions and 22 deletions
migrations/20230829165636_discovery.sql
@@ -0,0 +1,13 @@ | ||
1 | CREATE TYPE discovery_type AS ENUM | |
2 | ( | |
3 | 'instance', | |
4 | 'repository' | |
5 | ); | |
6 | ||
7 | CREATE TABLE IF NOT EXISTS discoveries | |
8 | ( | |
9 | discovery_hash TEXT PRIMARY KEY UNIQUE NOT NULL, | |
10 | discovery_time TEXT NOT NULL, | |
11 | discovery_type discovery_type NOT NULL, | |
12 | discovery TEXT NOT NULL | |
13 | ); | |
13 | \ No newline at end of file |
src/authentication.rs
@@ -32,9 +32,13 @@ impl AuthenticationTokenGranter { | ||
32 | 32 | let _secret_key = self.config["authentication"]["secret_key"] |
33 | 33 | .as_str() |
34 | 34 | .unwrap(); |
35 | let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) | |
36 | .await | |
37 | .unwrap(); | |
35 | let mut file = File::open( | |
36 | self.config["giterated"]["keys"]["private"] | |
37 | .as_str() | |
38 | .unwrap(), | |
39 | ) | |
40 | .await | |
41 | .unwrap(); | |
38 | 42 | |
39 | 43 | let mut key = vec![]; |
40 | 44 | file.read_to_end(&mut key).await.unwrap(); |
@@ -85,9 +89,13 @@ impl AuthenticationTokenGranter { | ||
85 | 89 | .as_str() |
86 | 90 | .unwrap(); |
87 | 91 | let private_key = { |
88 | let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) | |
89 | .await | |
90 | .unwrap(); | |
92 | let mut file = File::open( | |
93 | self.config["giterated"]["keys"]["private"] | |
94 | .as_str() | |
95 | .unwrap(), | |
96 | ) | |
97 | .await | |
98 | .unwrap(); | |
91 | 99 | |
92 | 100 | let mut key = vec![]; |
93 | 101 | file.read_to_end(&mut key).await.unwrap(); |
@@ -179,9 +187,13 @@ impl AuthenticationTokenGranter { | ||
179 | 187 | info!("Validated request for key extension"); |
180 | 188 | |
181 | 189 | let private_key = { |
182 | let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) | |
183 | .await | |
184 | .unwrap(); | |
190 | let mut file = File::open( | |
191 | self.config["giterated"]["keys"]["private"] | |
192 | .as_str() | |
193 | .unwrap(), | |
194 | ) | |
195 | .await | |
196 | .unwrap(); | |
185 | 197 | |
186 | 198 | let mut key = vec![]; |
187 | 199 | file.read_to_end(&mut key).await.unwrap(); |
src/backend/discovery.rs
@@ -8,7 +8,7 @@ pub struct GiteratedDiscoveryProtocol {} | ||
8 | 8 | |
9 | 9 | #[async_trait::async_trait] |
10 | 10 | impl DiscoveryBackend for GiteratedDiscoveryProtocol { |
11 | async fn try_handle(&mut self, request: DiscoveryMessage) -> Result<bool, Error> { | |
11 | async fn try_handle(&mut self, request: &DiscoveryMessage) -> Result<bool, Error> { | |
12 | 12 | todo!() |
13 | 13 | } |
14 | 14 |
src/backend/mod.rs
@@ -89,6 +89,6 @@ pub trait UserBackend: AuthBackend { | ||
89 | 89 | |
90 | 90 | #[async_trait::async_trait] |
91 | 91 | pub trait DiscoveryBackend { |
92 | async fn try_handle(&mut self, request: DiscoveryMessage) -> Result<bool, Error>; | |
92 | async fn try_handle(&mut self, request: &DiscoveryMessage) -> Result<bool, Error>; | |
93 | 93 | async fn search(&mut self, search: &str) -> Result<Vec<Repository>, Error>; |
94 | 94 | } |
src/connection.rs
@@ -15,7 +15,7 @@ use tokio_tungstenite::{tungstenite::Message, WebSocketStream}; | ||
15 | 15 | |
16 | 16 | use crate::{ |
17 | 17 | authentication::AuthenticationTokenGranter, |
18 | backend::{IssuesBackend, RepositoryBackend, UserBackend}, | |
18 | backend::{DiscoveryBackend, IssuesBackend, RepositoryBackend, UserBackend}, | |
19 | 19 | handshake::{HandshakeFinalize, HandshakeMessage, HandshakeResponse}, |
20 | 20 | listener::Listeners, |
21 | 21 | messages::{ |
@@ -63,6 +63,7 @@ pub async fn connection_worker( | ||
63 | 63 | backend: Arc<Mutex<dyn RepositoryBackend + Send>>, |
64 | 64 | user_backend: Arc<Mutex<dyn UserBackend + Send>>, |
65 | 65 | auth_granter: Arc<Mutex<AuthenticationTokenGranter>>, |
66 | discovery_backend: Arc<Mutex<dyn DiscoveryBackend + Send>>, | |
66 | 67 | addr: SocketAddr, |
67 | 68 | ) { |
68 | 69 | let mut handshaked = false; |
@@ -409,6 +410,13 @@ pub async fn connection_worker( | ||
409 | 410 | AuthenticationMessage::Response(_) => unreachable!(), |
410 | 411 | } |
411 | 412 | } |
413 | ||
414 | if let MessageKind::Discovery(message) = &message { | |
415 | let mut backend = discovery_backend.lock().await; | |
416 | backend.try_handle(message).await.unwrap(); | |
417 | ||
418 | continue; | |
419 | } | |
412 | 420 | } |
413 | 421 | |
414 | 422 | info!("Connection closed"); |
@@ -426,6 +434,7 @@ async fn send_and_get_listener( | ||
426 | 434 | } |
427 | 435 | MessageKind::Repository(repository) => (None, None, Some(repository.target.clone())), |
428 | 436 | MessageKind::Authentication(_) => todo!(), |
437 | MessageKind::Discovery(_) => todo!(), | |
429 | 438 | }; |
430 | 439 | |
431 | 440 | let target = match (&instance, &user, &repository) { |
src/main.rs
@@ -2,7 +2,10 @@ use anyhow::Error; | ||
2 | 2 | use connection::{connection_worker, Connections, RawConnection}; |
3 | 3 | use giterated_daemon::{ |
4 | 4 | authentication::AuthenticationTokenGranter, |
5 | backend::{git::GitBackend, user::UserAuth, RepositoryBackend, UserBackend}, | |
5 | backend::{ | |
6 | discovery::GiteratedDiscoveryProtocol, git::GitBackend, user::UserAuth, DiscoveryBackend, | |
7 | RepositoryBackend, UserBackend, | |
8 | }, | |
6 | 9 | connection, listener, |
7 | 10 | model::instance::Instance, |
8 | 11 | }; |
@@ -50,7 +53,7 @@ async fn main() -> Result<(), Error> { | ||
50 | 53 | let foo: GitBackend = GitBackend { |
51 | 54 | pg_pool: db_pool.clone(), |
52 | 55 | repository_folder: String::from( |
53 | config["repository"]["backend"]["git"]["root"] | |
56 | config["giterated"]["backend"]["git"]["root"] | |
54 | 57 | .as_str() |
55 | 58 | .unwrap(), |
56 | 59 | ), |
@@ -68,6 +71,9 @@ async fn main() -> Result<(), Error> { | ||
68 | 71 | token_granter.clone(), |
69 | 72 | ))); |
70 | 73 | |
74 | let discovery_backend: Arc<Mutex<dyn DiscoveryBackend + Send>> = | |
75 | Arc::new(Mutex::new(GiteratedDiscoveryProtocol {})); | |
76 | ||
71 | 77 | info!("Connected"); |
72 | 78 | |
73 | 79 | loop { |
@@ -107,6 +113,7 @@ async fn main() -> Result<(), Error> { | ||
107 | 113 | repository_backend.clone(), |
108 | 114 | user_backend.clone(), |
109 | 115 | token_granter.clone(), |
116 | discovery_backend.clone(), | |
110 | 117 | address, |
111 | 118 | )), |
112 | 119 | }; |
src/messages/discovery.rs
@@ -5,31 +5,31 @@ use crate::model::discovery::DiscoveryItem; | ||
5 | 5 | |
6 | 6 | use super::InstanceAuthenticated; |
7 | 7 | |
8 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
8 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
9 | 9 | pub struct DiscoveryMessage { |
10 | 10 | pub message: InstanceAuthenticated<DiscoveryMessageKind>, |
11 | 11 | } |
12 | 12 | |
13 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
13 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
14 | 14 | pub enum DiscoveryMessageKind { |
15 | 15 | Offer(DiscoveryOffer), |
16 | 16 | Request(DiscoveryRequest), |
17 | 17 | Discoveries(Discoveries), |
18 | 18 | } |
19 | 19 | |
20 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
20 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
21 | 21 | pub struct DiscoveryOffer { |
22 | 22 | pub earliest: DateTime<Utc>, |
23 | 23 | pub hashes: Vec<u128>, |
24 | 24 | } |
25 | 25 | |
26 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
26 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
27 | 27 | pub struct DiscoveryRequest { |
28 | 28 | pub since: DateTime<Utc>, |
29 | 29 | pub hashes: Vec<u128>, |
30 | 30 | } |
31 | 31 | |
32 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
32 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
33 | 33 | pub struct Discoveries { |
34 | 34 | pub discoveries: Vec<DiscoveryItem>, |
35 | 35 | } |
src/messages/mod.rs
@@ -16,7 +16,10 @@ use crate::{ | ||
16 | 16 | model::{instance::Instance, user::User}, |
17 | 17 | }; |
18 | 18 | |
19 | use self::{authentication::AuthenticationMessage, repository::RepositoryMessage}; | |
19 | use self::{ | |
20 | authentication::AuthenticationMessage, discovery::DiscoveryMessage, | |
21 | repository::RepositoryMessage, | |
22 | }; | |
20 | 23 | |
21 | 24 | pub mod authentication; |
22 | 25 | pub mod discovery; |
@@ -29,6 +32,7 @@ pub enum MessageKind { | ||
29 | 32 | Handshake(HandshakeMessage), |
30 | 33 | Repository(RepositoryMessage), |
31 | 34 | Authentication(AuthenticationMessage), |
35 | Discovery(DiscoveryMessage), | |
32 | 36 | } |
33 | 37 | |
34 | 38 | /// An authenticated message, where the instance is authenticating |
src/model/discovery.rs
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; | ||
2 | 2 | |
3 | 3 | use crate::model::{instance::Instance, repository::Repository}; |
4 | 4 | |
5 | #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
5 | #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] | |
6 | 6 | pub enum DiscoveryItem { |
7 | 7 | Instance { |
8 | 8 | instance: Instance, |
src/model/instance.rs
@@ -1,6 +1,7 @@ | ||
1 | 1 | use std::str::FromStr; |
2 | 2 | |
3 | 3 | use serde::{Deserialize, Serialize}; |
4 | use thiserror::Error; | |
4 | 5 | |
5 | 6 | pub struct InstanceMeta { |
6 | 7 | pub url: String, |
@@ -36,9 +37,15 @@ impl ToString for Instance { | ||
36 | 37 | } |
37 | 38 | |
38 | 39 | impl FromStr for Instance { |
39 | type Err = (); | |
40 | type Err = InstanceParseError; | |
40 | 41 | |
41 | 42 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
42 | 43 | Ok(Self { url: s.to_string() }) |
43 | 44 | } |
44 | 45 | } |
46 | ||
47 | #[derive(Debug, Error)] | |
48 | pub enum InstanceParseError { | |
49 | #[error("invalid format")] | |
50 | InvalidFormat, | |
51 | } |