JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

woo

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨2d48bc0

Showing ⁨⁨10⁩ changed files⁩ with ⁨⁨74⁩ insertions⁩ and ⁨⁨22⁩ deletions⁩

migrations/20230829165636_discovery.sql

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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

View file
@@ -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 }