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

ambee/giterated

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

Fixes

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨73a5af5

⁨giterated-daemon/src/main.rs⁩ - ⁨5128⁩ bytes
Raw
1 use anyhow::Error;
2 use connection::{Connections, RawConnection};
3 use giterated_daemon::{
4 authentication::AuthenticationTokenGranter,
5 backend::{
6 git::GitBackend, settings::DatabaseSettings, user::UserAuth, RepositoryBackend, UserBackend,
7 },
8 connection::{self, wrapper::connection_wrapper},
9 database_backend::DatabaseBackend,
10 federation::connections::InstanceConnections,
11 };
12
13 use giterated_models::instance::Instance;
14
15 use sqlx::{postgres::PgConnectOptions, ConnectOptions, PgPool};
16 use std::{net::SocketAddr, str::FromStr, sync::Arc};
17 use tokio::{
18 fs::File,
19 io::{AsyncRead, AsyncReadExt, AsyncWrite},
20 net::{TcpListener, TcpStream},
21 sync::Mutex,
22 };
23 use tokio_tungstenite::{accept_async, WebSocketStream};
24 use toml::Table;
25
26 #[macro_use]
27 extern crate tracing;
28
29 #[tokio::main]
30 async fn main() -> Result<(), Error> {
31 tracing_subscriber::fmt::init();
32 let config: Table = {
33 let mut file = File::open("Giterated.toml").await?;
34 let mut text = String::new();
35 file.read_to_string(&mut text).await?;
36 text.parse()?
37 };
38 let mut listener = TcpListener::bind(config["giterated"]["bind"].as_str().unwrap()).await?;
39 let connections: Arc<Mutex<Connections>> = Arc::default();
40 let instance_connections: Arc<Mutex<InstanceConnections>> = Arc::default();
41 let db_conn_options = PgConnectOptions::new()
42 .host(config["postgres"]["host"].as_str().unwrap())
43 .port(config["postgres"]["port"].as_integer().unwrap() as u16)
44 .database(config["postgres"]["database"].as_str().unwrap())
45 .username(config["postgres"]["user"].as_str().unwrap())
46 .password(config["postgres"]["password"].as_str().unwrap())
47 .log_statements(log::LevelFilter::Off);
48 let db_pool = PgPool::connect_with(db_conn_options).await?;
49
50 debug!("Running database migrations...");
51 sqlx::migrate!().run(&db_pool).await?;
52 info!("Connected");
53
54 let settings = Arc::new(Mutex::new(DatabaseSettings {
55 pg_pool: db_pool.clone(),
56 }));
57
58 let repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>> =
59 Arc::new(Mutex::new(GitBackend {
60 pg_pool: db_pool.clone(),
61 repository_folder: String::from(
62 config["giterated"]["backend"]["git"]["root"]
63 .as_str()
64 .unwrap(),
65 ),
66 instance: Instance::from_str(config["giterated"]["instance"].as_str().unwrap())
67 .unwrap(),
68 settings_provider: settings.clone(),
69 }));
70
71 let token_granter = Arc::new(Mutex::new(AuthenticationTokenGranter {
72 config: config.clone(),
73 instance: Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap(),
74 }));
75
76 let user_backend: Arc<Mutex<dyn UserBackend + Send>> = Arc::new(Mutex::new(UserAuth::new(
77 db_pool.clone(),
78 &Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap(),
79 token_granter.clone(),
80 settings.clone(),
81 )));
82
83 info!("Connected");
84
85 let database_backend = DatabaseBackend::new(
86 Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap(),
87 user_backend.clone(),
88 repository_backend.clone(),
89 );
90
91 loop {
92 let stream = accept_stream(&mut listener).await;
93 info!("Connected");
94
95 let (stream, address) = match stream {
96 Ok(stream) => stream,
97 Err(err) => {
98 error!("Failed to accept connection. {:?}", err);
99 continue;
100 }
101 };
102
103 info!("Accepted connection from {}", address);
104
105 let connection = accept_websocket_connection(stream).await;
106
107 let connection = match connection {
108 Ok(connection) => connection,
109 Err(err) => {
110 error!(
111 "Failed to initiate Websocket connection from {}. {:?}",
112 address, err
113 );
114 continue;
115 }
116 };
117
118 info!("Websocket connection established with {}", address);
119
120 let connection = RawConnection {
121 task: tokio::spawn(connection_wrapper(
122 connection,
123 connections.clone(),
124 repository_backend.clone(),
125 user_backend.clone(),
126 token_granter.clone(),
127 settings.clone(),
128 address,
129 Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap(),
130 instance_connections.clone(),
131 config.clone(),
132 database_backend.clone(),
133 )),
134 };
135
136 connections.lock().await.connections.push(connection);
137 }
138 }
139
140 async fn accept_stream(listener: &mut TcpListener) -> Result<(TcpStream, SocketAddr), Error> {
141 let stream = listener.accept().await?;
142
143 Ok(stream)
144 }
145
146 async fn accept_websocket_connection<S: AsyncRead + AsyncWrite + Unpin>(
147 stream: S,
148 ) -> Result<WebSocketStream<S>, Error> {
149 let connection = accept_async(stream).await?;
150
151 Ok(connection)
152 }
153