Changes
parent: tbd commit: 0b2a26d
Showing 11 changed files with 338 insertions and 24 deletions
.gitignore
@@ -1,3 +1,4 @@ | ||
1 | 1 | /target |
2 | 2 | .idea |
3 | 3 | .env |
4 | Giterated.toml | |
4 | \ No newline at end of file |
Cargo.lock
@@ -99,6 +99,12 @@ dependencies = [ | ||
99 | 99 | |
100 | 100 | [[package]] |
101 | 101 | name = "base64" |
102 | version = "0.13.1" | |
103 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
104 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" | |
105 | ||
106 | [[package]] | |
107 | name = "base64" | |
102 | 108 | version = "0.21.3" |
103 | 109 | source = "registry+https://github.com/rust-lang/crates.io-index" |
104 | 110 | checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" |
@@ -178,7 +184,7 @@ dependencies = [ | ||
178 | 184 | "js-sys", |
179 | 185 | "num-traits", |
180 | 186 | "serde", |
181 | "time", | |
187 | "time 0.1.45", | |
182 | 188 | "wasm-bindgen", |
183 | 189 | "winapi", |
184 | 190 | ] |
@@ -276,6 +282,12 @@ dependencies = [ | ||
276 | 282 | ] |
277 | 283 | |
278 | 284 | [[package]] |
285 | name = "deranged" | |
286 | version = "0.3.8" | |
287 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
288 | checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" | |
289 | ||
290 | [[package]] | |
279 | 291 | name = "digest" |
280 | 292 | version = "0.10.7" |
281 | 293 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -529,12 +541,15 @@ dependencies = [ | ||
529 | 541 | "chrono", |
530 | 542 | "futures-util", |
531 | 543 | "git2", |
544 | "jsonwebtoken", | |
545 | "log", | |
532 | 546 | "serde", |
533 | 547 | "serde_json", |
534 | 548 | "sqlx", |
535 | 549 | "thiserror", |
536 | 550 | "tokio", |
537 | 551 | "tokio-tungstenite", |
552 | "toml", | |
538 | 553 | "tracing", |
539 | 554 | "tracing-subscriber", |
540 | 555 | ] |
@@ -700,6 +715,20 @@ dependencies = [ | ||
700 | 715 | ] |
701 | 716 | |
702 | 717 | [[package]] |
718 | name = "jsonwebtoken" | |
719 | version = "8.3.0" | |
720 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
721 | checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" | |
722 | dependencies = [ | |
723 | "base64 0.21.3", | |
724 | "pem", | |
725 | "ring", | |
726 | "serde", | |
727 | "serde_json", | |
728 | "simple_asn1", | |
729 | ] | |
730 | ||
731 | [[package]] | |
703 | 732 | name = "lazy_static" |
704 | 733 | version = "1.4.0" |
705 | 734 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -873,6 +902,17 @@ dependencies = [ | ||
873 | 902 | ] |
874 | 903 | |
875 | 904 | [[package]] |
905 | name = "num-bigint" | |
906 | version = "0.4.4" | |
907 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
908 | checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" | |
909 | dependencies = [ | |
910 | "autocfg", | |
911 | "num-integer", | |
912 | "num-traits", | |
913 | ] | |
914 | ||
915 | [[package]] | |
876 | 916 | name = "num-bigint-dig" |
877 | 917 | version = "0.8.4" |
878 | 918 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1025,6 +1065,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1025 | 1065 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" |
1026 | 1066 | |
1027 | 1067 | [[package]] |
1068 | name = "pem" | |
1069 | version = "1.1.1" | |
1070 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1071 | checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" | |
1072 | dependencies = [ | |
1073 | "base64 0.13.1", | |
1074 | ] | |
1075 | ||
1076 | [[package]] | |
1028 | 1077 | name = "pem-rfc7468" |
1029 | 1078 | version = "0.7.0" |
1030 | 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1162,6 +1211,21 @@ dependencies = [ | ||
1162 | 1211 | ] |
1163 | 1212 | |
1164 | 1213 | [[package]] |
1214 | name = "ring" | |
1215 | version = "0.16.20" | |
1216 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1217 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" | |
1218 | dependencies = [ | |
1219 | "cc", | |
1220 | "libc", | |
1221 | "once_cell", | |
1222 | "spin 0.5.2", | |
1223 | "untrusted", | |
1224 | "web-sys", | |
1225 | "winapi", | |
1226 | ] | |
1227 | ||
1228 | [[package]] | |
1165 | 1229 | name = "rsa" |
1166 | 1230 | version = "0.9.2" |
1167 | 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1278,6 +1342,15 @@ dependencies = [ | ||
1278 | 1342 | ] |
1279 | 1343 | |
1280 | 1344 | [[package]] |
1345 | name = "serde_spanned" | |
1346 | version = "0.6.3" | |
1347 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1348 | checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" | |
1349 | dependencies = [ | |
1350 | "serde", | |
1351 | ] | |
1352 | ||
1353 | [[package]] | |
1281 | 1354 | name = "sha1" |
1282 | 1355 | version = "0.10.5" |
1283 | 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1328,6 +1401,18 @@ dependencies = [ | ||
1328 | 1401 | ] |
1329 | 1402 | |
1330 | 1403 | [[package]] |
1404 | name = "simple_asn1" | |
1405 | version = "0.6.2" | |
1406 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1407 | checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" | |
1408 | dependencies = [ | |
1409 | "num-bigint", | |
1410 | "num-traits", | |
1411 | "thiserror", | |
1412 | "time 0.3.28", | |
1413 | ] | |
1414 | ||
1415 | [[package]] | |
1331 | 1416 | name = "slab" |
1332 | 1417 | version = "0.4.9" |
1333 | 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1489,7 +1574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1489 | 1574 | checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" |
1490 | 1575 | dependencies = [ |
1491 | 1576 | "atoi", |
1492 | "base64", | |
1577 | "base64 0.21.3", | |
1493 | 1578 | "bitflags 2.4.0", |
1494 | 1579 | "byteorder", |
1495 | 1580 | "bytes", |
@@ -1532,7 +1617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1532 | 1617 | checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" |
1533 | 1618 | dependencies = [ |
1534 | 1619 | "atoi", |
1535 | "base64", | |
1620 | "base64 0.21.3", | |
1536 | 1621 | "bitflags 2.4.0", |
1537 | 1622 | "byteorder", |
1538 | 1623 | "chrono", |
@@ -1681,6 +1766,34 @@ dependencies = [ | ||
1681 | 1766 | ] |
1682 | 1767 | |
1683 | 1768 | [[package]] |
1769 | name = "time" | |
1770 | version = "0.3.28" | |
1771 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1772 | checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" | |
1773 | dependencies = [ | |
1774 | "deranged", | |
1775 | "itoa", | |
1776 | "serde", | |
1777 | "time-core", | |
1778 | "time-macros", | |
1779 | ] | |
1780 | ||
1781 | [[package]] | |
1782 | name = "time-core" | |
1783 | version = "0.1.1" | |
1784 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1785 | checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" | |
1786 | ||
1787 | [[package]] | |
1788 | name = "time-macros" | |
1789 | version = "0.2.14" | |
1790 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1791 | checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" | |
1792 | dependencies = [ | |
1793 | "time-core", | |
1794 | ] | |
1795 | ||
1796 | [[package]] | |
1684 | 1797 | name = "tinyvec" |
1685 | 1798 | version = "1.6.0" |
1686 | 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1749,6 +1862,40 @@ dependencies = [ | ||
1749 | 1862 | ] |
1750 | 1863 | |
1751 | 1864 | [[package]] |
1865 | name = "toml" | |
1866 | version = "0.7.6" | |
1867 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1868 | checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" | |
1869 | dependencies = [ | |
1870 | "serde", | |
1871 | "serde_spanned", | |
1872 | "toml_datetime", | |
1873 | "toml_edit", | |
1874 | ] | |
1875 | ||
1876 | [[package]] | |
1877 | name = "toml_datetime" | |
1878 | version = "0.6.3" | |
1879 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1880 | checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" | |
1881 | dependencies = [ | |
1882 | "serde", | |
1883 | ] | |
1884 | ||
1885 | [[package]] | |
1886 | name = "toml_edit" | |
1887 | version = "0.19.14" | |
1888 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1889 | checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" | |
1890 | dependencies = [ | |
1891 | "indexmap", | |
1892 | "serde", | |
1893 | "serde_spanned", | |
1894 | "toml_datetime", | |
1895 | "winnow", | |
1896 | ] | |
1897 | ||
1898 | [[package]] | |
1752 | 1899 | name = "tracing" |
1753 | 1900 | version = "0.1.37" |
1754 | 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1866,6 +2013,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1866 | 2013 | checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" |
1867 | 2014 | |
1868 | 2015 | [[package]] |
2016 | name = "untrusted" | |
2017 | version = "0.7.1" | |
2018 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2019 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" | |
2020 | ||
2021 | [[package]] | |
1869 | 2022 | name = "url" |
1870 | 2023 | version = "2.4.0" |
1871 | 2024 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1967,6 +2120,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1967 | 2120 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" |
1968 | 2121 | |
1969 | 2122 | [[package]] |
2123 | name = "web-sys" | |
2124 | version = "0.3.64" | |
2125 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2126 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" | |
2127 | dependencies = [ | |
2128 | "js-sys", | |
2129 | "wasm-bindgen", | |
2130 | ] | |
2131 | ||
2132 | [[package]] | |
1970 | 2133 | name = "whoami" |
1971 | 2134 | version = "1.4.1" |
1972 | 2135 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2070,6 +2233,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2070 | 2233 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" |
2071 | 2234 | |
2072 | 2235 | [[package]] |
2236 | name = "winnow" | |
2237 | version = "0.5.15" | |
2238 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2239 | checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" | |
2240 | dependencies = [ | |
2241 | "memchr", | |
2242 | ] | |
2243 | ||
2244 | [[package]] | |
2073 | 2245 | name = "zeroize" |
2074 | 2246 | version = "1.6.0" |
2075 | 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" |
Cargo.toml
@@ -13,6 +13,10 @@ futures-util = "*" | ||
13 | 13 | serde = { version = "1", features = [ "derive" ]} |
14 | 14 | serde_json = "1.0" |
15 | 15 | tracing-subscriber = "0.3" |
16 | jsonwebtoken = { version = "*", features = ["use_pem"]} | |
17 | log = "*" | |
18 | ||
19 | toml = { version = "0.7" } | |
16 | 20 | |
17 | 21 | chrono = { version = "0.4", features = [ "serde" ] } |
18 | 22 | async-trait = "0.1" |
src/authentication.rs
@@ -0,0 +1,76 @@ | ||
1 | use std::{error::Error, time::SystemTime}; | |
2 | ||
3 | use chrono::Duration; | |
4 | use jsonwebtoken::{encode, Algorithm, EncodingKey}; | |
5 | use serde::{Deserialize, Serialize}; | |
6 | use tokio::{fs::File, io::AsyncReadExt}; | |
7 | use toml::Table; | |
8 | ||
9 | use crate::{ | |
10 | messages::authentication::{AuthenticationTokenRequest, AuthenticationTokenResponse}, | |
11 | model::{instance::Instance, user::User}, | |
12 | }; | |
13 | ||
14 | #[derive(Debug, Serialize, Deserialize)] | |
15 | struct UserTokenMetadata { | |
16 | user: User, | |
17 | generated_for: Instance, | |
18 | exp: u64, | |
19 | } | |
20 | ||
21 | pub struct AuthenticationTokenGranter { | |
22 | pub config: Table, | |
23 | } | |
24 | ||
25 | impl AuthenticationTokenGranter { | |
26 | pub async fn token_request( | |
27 | &mut self, | |
28 | request: AuthenticationTokenRequest, | |
29 | ) -> Result<AuthenticationTokenResponse, Box<dyn Error + Send>> { | |
30 | let secret_key = self.config["authentication"]["secret_key"] | |
31 | .as_str() | |
32 | .unwrap(); | |
33 | let private_key = { | |
34 | let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) | |
35 | .await | |
36 | .unwrap(); | |
37 | ||
38 | let mut key = vec![]; | |
39 | file.read_to_end(&mut key).await.unwrap(); | |
40 | ||
41 | key | |
42 | }; | |
43 | ||
44 | if request.secret_key != secret_key { | |
45 | error!("Incorrect secret key!"); | |
46 | ||
47 | panic!() | |
48 | } | |
49 | ||
50 | let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap(); | |
51 | ||
52 | let claims = UserTokenMetadata { | |
53 | user: User { | |
54 | username: String::from("ambee"), | |
55 | instance: Instance { | |
56 | url: String::from("giterated.dev"), | |
57 | }, | |
58 | }, | |
59 | generated_for: Instance { | |
60 | url: String::from("giterated.dev"), | |
61 | }, | |
62 | exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap() | |
63 | + std::time::Duration::from_secs(24 * 60 * 60)) | |
64 | .as_secs(), | |
65 | }; | |
66 | ||
67 | let token = encode( | |
68 | &jsonwebtoken::Header::new(Algorithm::RS256), | |
69 | &claims, | |
70 | &encoding_key, | |
71 | ) | |
72 | .unwrap(); | |
73 | ||
74 | Ok(AuthenticationTokenResponse { token }) | |
75 | } | |
76 | } |
src/backend/git.rs
@@ -151,7 +151,7 @@ impl GitBackend { | ||
151 | 151 | } |
152 | 152 | |
153 | 153 | // Delete the repository from the database |
154 | return match sqlx::query!( | |
154 | match sqlx::query!( | |
155 | 155 | "DELETE FROM repositories WHERE instance_url = $1 AND username = $2 AND name = $3", |
156 | 156 | instance_url, |
157 | 157 | username, |
@@ -162,7 +162,7 @@ impl GitBackend { | ||
162 | 162 | { |
163 | 163 | Ok(deleted) => Ok(deleted.rows_affected()), |
164 | 164 | Err(err) => Err(GitBackendError::FailedDeletingFromDatabase(err)), |
165 | }; | |
165 | } | |
166 | 166 | } |
167 | 167 | |
168 | 168 | // TODO: Find where this fits |
@@ -197,7 +197,7 @@ impl GitBackend { | ||
197 | 197 | let current_path = dd.new_file().path().unwrap(); |
198 | 198 | |
199 | 199 | // Path or directory |
200 | if current_path.eq(Path::new(&path)) || current_path.starts_with(&path) { | |
200 | if current_path.eq(Path::new(&path)) || current_path.starts_with(path) { | |
201 | 201 | return Ok(commit.into()); |
202 | 202 | } |
203 | 203 | } |
@@ -215,7 +215,7 @@ impl RepositoryBackend for GitBackend { | ||
215 | 215 | request: &CreateRepositoryRequest, |
216 | 216 | ) -> Result<CreateRepositoryResponse, Box<dyn Error + Send>> { |
217 | 217 | // Check if repository already exists in the database |
218 | if let Ok(repository) = self | |
218 | if let Ok(_repository) = self | |
219 | 219 | .find_by_instance_username_name( |
220 | 220 | request.owner.instance.url.as_str(), |
221 | 221 | request.owner.username.as_str(), |
@@ -304,7 +304,7 @@ impl RepositoryBackend for GitBackend { | ||
304 | 304 | |
305 | 305 | if !repository.can_user_view_repository( |
306 | 306 | request.owner.instance.url.as_str(), |
307 | Some(&request.owner.username.as_str()), | |
307 | Some(request.owner.username.as_str()), | |
308 | 308 | ) { |
309 | 309 | return Err(Box::new(GitBackendError::RepositoryNotFound { |
310 | 310 | instance_url: request.owner.instance.url.clone(), |
@@ -361,7 +361,7 @@ impl RepositoryBackend for GitBackend { | ||
361 | 361 | let mut current_path = rev_name.replace("refs/heads/", ""); |
362 | 362 | |
363 | 363 | // Get the commit tree |
364 | let mut git_tree = if let Some(path) = &request.path { | |
364 | let git_tree = if let Some(path) = &request.path { | |
365 | 365 | // Add it to our full path string |
366 | 366 | current_path.push_str(format!("/{}", path).as_str()); |
367 | 367 | // Get the specified path, return an error if it wasn't found. |
@@ -400,7 +400,7 @@ impl RepositoryBackend for GitBackend { | ||
400 | 400 | } |
401 | 401 | |
402 | 402 | // Could possibly be done better |
403 | let path = if let Some(path) = current_path.split_once("/") { | |
403 | let path = if let Some(path) = current_path.split_once('/') { | |
404 | 404 | format!("{}/{}", path.1, entry.name().unwrap()) |
405 | 405 | } else { |
406 | 406 | entry.name().unwrap().to_string() |
src/connection.rs
@@ -12,6 +12,7 @@ use tokio::{ | ||
12 | 12 | use tokio_tungstenite::{tungstenite::Message, WebSocketStream}; |
13 | 13 | |
14 | 14 | use crate::{ |
15 | authentication::AuthenticationTokenGranter, | |
15 | 16 | backend::{IssuesBackend, RepositoryBackend}, |
16 | 17 | handshake::{HandshakeFinalize, HandshakeMessage, HandshakeResponse}, |
17 | 18 | listener::Listeners, |
@@ -54,6 +55,7 @@ pub async fn connection_worker( | ||
54 | 55 | listeners: Arc<Mutex<Listeners>>, |
55 | 56 | connections: Arc<Mutex<Connections>>, |
56 | 57 | backend: Arc<Mutex<dyn RepositoryBackend + Send>>, |
58 | auth_granter: Arc<Mutex<AuthenticationTokenGranter>>, | |
57 | 59 | addr: SocketAddr, |
58 | 60 | ) { |
59 | 61 | let mut handshaked = false; |
@@ -183,7 +185,7 @@ pub async fn connection_worker( | ||
183 | 185 | RepositoryMessageKind::Request(request) => match request { |
184 | 186 | RepositoryRequest::CreateRepository(request) => { |
185 | 187 | let mut backend = backend.lock().await; |
186 | let response = backend.create_repository(request); | |
188 | let response = backend.create_repository(request).await; | |
187 | 189 | |
188 | 190 | let response = match response { |
189 | 191 | Ok(response) => response, |
@@ -241,7 +243,7 @@ pub async fn connection_worker( | ||
241 | 243 | } |
242 | 244 | RepositoryRequest::RepositoryInfo(request) => { |
243 | 245 | let mut backend = backend.lock().await; |
244 | let response = backend.repository_info(request); | |
246 | let response = backend.repository_info(request).await; | |
245 | 247 | |
246 | 248 | let response = match response { |
247 | 249 | Ok(response) => response, |
src/lib.rs
@@ -1,3 +1,4 @@ | ||
1 | pub mod authentication; | |
1 | 2 | pub mod backend; |
2 | 3 | pub mod connection; |
3 | 4 | pub mod handshake; |
src/main.rs
@@ -2,16 +2,20 @@ use std::{error::Error, net::SocketAddr, sync::Arc}; | ||
2 | 2 | |
3 | 3 | use connection::{connection_worker, Connections, RawConnection}; |
4 | 4 | use giterated_daemon::{ |
5 | authentication::AuthenticationTokenGranter, | |
5 | 6 | backend::{git::GitBackend, RepositoryBackend}, |
6 | 7 | connection, listener, |
7 | 8 | }; |
8 | 9 | use listener::Listeners; |
10 | use sqlx::{postgres::PgConnectOptions, ConnectOptions, PgPool}; | |
9 | 11 | use tokio::{ |
10 | io::{AsyncRead, AsyncWrite}, | |
12 | fs::File, | |
13 | io::{AsyncRead, AsyncReadExt, AsyncWrite}, | |
11 | 14 | net::{TcpListener, TcpStream}, |
12 | 15 | sync::Mutex, |
13 | 16 | }; |
14 | 17 | use tokio_tungstenite::{accept_async, WebSocketStream}; |
18 | use toml::Table; | |
15 | 19 | |
16 | 20 | #[macro_use] |
17 | 21 | extern crate tracing; |
@@ -19,10 +23,36 @@ extern crate tracing; | ||
19 | 23 | #[tokio::main] |
20 | 24 | async fn main() -> Result<(), Box<dyn Error>> { |
21 | 25 | tracing_subscriber::fmt::init(); |
22 | let mut listener = TcpListener::bind("127.0.0.1:8080").await?; | |
26 | let mut listener = TcpListener::bind("0.0.0.0:7270").await?; | |
23 | 27 | let connections: Arc<Mutex<Connections>> = Arc::default(); |
24 | 28 | let listeners: Arc<Mutex<Listeners>> = Arc::default(); |
25 | let backend: Arc<Mutex<dyn RepositoryBackend + Send>> = Arc::new(Mutex::new(GitBackend::new())); | |
29 | let config: Table = { | |
30 | let mut file = File::open("Giterated.toml").await?; | |
31 | let mut text = String::new(); | |
32 | file.read_to_string(&mut text).await?; | |
33 | text.parse()? | |
34 | }; | |
35 | let db_conn_options = PgConnectOptions::new() | |
36 | .host(config["postgres"]["host"].as_str().unwrap()) | |
37 | .port(config["postgres"]["port"].as_integer().unwrap() as u16) | |
38 | .database(config["postgres"]["database"].as_str().unwrap()) | |
39 | .username(config["postgres"]["user"].as_str().unwrap()) | |
40 | .password(config["postgres"]["password"].as_str().unwrap()) | |
41 | .log_statements(log::LevelFilter::Off) | |
42 | .to_owned(); | |
43 | let db_pool = PgPool::connect_with(db_conn_options).await?; | |
44 | ||
45 | let repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>> = Arc::new(Mutex::new({ | |
46 | let foo: GitBackend = GitBackend { | |
47 | pg_pool: db_pool, | |
48 | repository_folder: String::from("/tmp/foo"), | |
49 | }; | |
50 | foo | |
51 | })); | |
52 | ||
53 | let token_granter = Arc::new(Mutex::new(AuthenticationTokenGranter { | |
54 | config: config.clone(), | |
55 | })); | |
26 | 56 | |
27 | 57 | loop { |
28 | 58 | let stream = accept_stream(&mut listener).await; |
@@ -57,7 +87,8 @@ async fn main() -> Result<(), Box<dyn Error>> { | ||
57 | 87 | connection, |
58 | 88 | listeners.clone(), |
59 | 89 | connections.clone(), |
60 | backend.clone(), | |
90 | repository_backend.clone(), | |
91 | token_granter.clone(), | |
61 | 92 | address, |
62 | 93 | )), |
63 | 94 | }; |
src/messages/authentication.rs
@@ -0,0 +1,29 @@ | ||
1 | use serde::{Deserialize, Serialize}; | |
2 | ||
3 | #[derive(Clone, Serialize, Deserialize)] | |
4 | pub enum AuthenticationMessage { | |
5 | Request(AuthenticationRequest), | |
6 | Response(AuthenticationResponse), | |
7 | } | |
8 | ||
9 | #[derive(Clone, Serialize, Deserialize)] | |
10 | pub enum AuthenticationRequest { | |
11 | AuthenticationToken(AuthenticationTokenRequest), | |
12 | } | |
13 | ||
14 | #[derive(Clone, Serialize, Deserialize)] | |
15 | pub enum AuthenticationResponse { | |
16 | AuthenticationToken(AuthenticationTokenResponse), | |
17 | } | |
18 | ||
19 | #[derive(Clone, Serialize, Deserialize)] | |
20 | pub struct AuthenticationTokenRequest { | |
21 | pub secret_key: String, | |
22 | pub username: String, | |
23 | pub password: String, | |
24 | } | |
25 | ||
26 | #[derive(Clone, Serialize, Deserialize)] | |
27 | pub struct AuthenticationTokenResponse { | |
28 | pub token: String, | |
29 | } |
src/messages/mod.rs
@@ -2,8 +2,9 @@ use serde::{Deserialize, Serialize}; | ||
2 | 2 | |
3 | 3 | use crate::handshake::HandshakeMessage; |
4 | 4 | |
5 | use self::repository::RepositoryMessage; | |
5 | use self::{authentication::AuthenticationMessage, repository::RepositoryMessage}; | |
6 | 6 | |
7 | pub mod authentication; | |
7 | 8 | pub mod issues; |
8 | 9 | pub mod repository; |
9 | 10 | pub mod user; |
@@ -12,4 +13,5 @@ pub mod user; | ||
12 | 13 | pub enum MessageKind { |
13 | 14 | Handshake(HandshakeMessage), |
14 | 15 | Repository(RepositoryMessage), |
16 | Authentication(AuthenticationMessage), | |
15 | 17 | } |
src/model/repository.rs
@@ -101,9 +101,7 @@ impl From<git2::Commit<'_>> for Commit { | ||
101 | 101 | fn from(commit: git2::Commit<'_>) -> Self { |
102 | 102 | Self { |
103 | 103 | oid: commit.id().to_string(), |
104 | message: commit | |
105 | .message() | |
106 | .map_or(None, |message| Some(message.to_string())), | |
104 | message: commit.message().map(|message| message.to_string()), | |
107 | 105 | author: commit.author().into(), |
108 | 106 | committer: commit.committer().into(), |
109 | 107 | time: chrono::NaiveDateTime::from_timestamp_opt(commit.time().seconds(), 0).unwrap(), |
@@ -123,10 +121,8 @@ pub struct CommitSignature { | ||
123 | 121 | impl From<git2::Signature<'_>> for CommitSignature { |
124 | 122 | fn from(signature: git2::Signature<'_>) -> Self { |
125 | 123 | Self { |
126 | name: signature.name().map_or(None, |name| Some(name.to_string())), | |
127 | email: signature | |
128 | .email() | |
129 | .map_or(None, |email| Some(email.to_string())), | |
124 | name: signature.name().map(|name| name.to_string()), | |
125 | email: signature.email().map(|email| email.to_string()), | |
130 | 126 | time: chrono::NaiveDateTime::from_timestamp_opt(signature.when().seconds(), 0).unwrap(), |
131 | 127 | } |
132 | 128 | } |