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: ⁨74f247e

Showing ⁨⁨9⁩ changed files⁩ with ⁨⁨397⁩ insertions⁩ and ⁨⁨11⁩ deletions⁩

Cargo.lock

View file
@@ -315,6 +315,15 @@ dependencies = [
315 315 ]
316 316
317 317 [[package]]
318 name = "encoding_rs"
319 version = "0.8.33"
320 source = "registry+https://github.com/rust-lang/crates.io-index"
321 checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
322 dependencies = [
323 "cfg-if",
324 ]
325
326 [[package]]
318 327 name = "equivalent"
319 328 version = "1.0.1"
320 329 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -543,6 +552,9 @@ dependencies = [
543 552 "git2",
544 553 "jsonwebtoken",
545 554 "log",
555 "rand",
556 "reqwest",
557 "rsa",
546 558 "serde",
547 559 "serde_json",
548 560 "sqlx",
@@ -555,6 +567,31 @@ dependencies = [
555 567 ]
556 568
557 569 [[package]]
570 name = "h2"
571 version = "0.3.21"
572 source = "registry+https://github.com/rust-lang/crates.io-index"
573 checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
574 dependencies = [
575 "bytes",
576 "fnv",
577 "futures-core",
578 "futures-sink",
579 "futures-util",
580 "http",
581 "indexmap 1.9.3",
582 "slab",
583 "tokio",
584 "tokio-util",
585 "tracing",
586 ]
587
588 [[package]]
589 name = "hashbrown"
590 version = "0.12.3"
591 source = "registry+https://github.com/rust-lang/crates.io-index"
592 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
593
594 [[package]]
558 595 name = "hashbrown"
559 596 version = "0.14.0"
560 597 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -570,7 +607,7 @@ version = "0.8.3"
570 607 source = "registry+https://github.com/rust-lang/crates.io-index"
571 608 checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f"
572 609 dependencies = [
573 "hashbrown",
610 "hashbrown 0.14.0",
574 611 ]
575 612
576 613 [[package]]
@@ -633,12 +670,66 @@ dependencies = [
633 670 ]
634 671
635 672 [[package]]
673 name = "http-body"
674 version = "0.4.5"
675 source = "registry+https://github.com/rust-lang/crates.io-index"
676 checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
677 dependencies = [
678 "bytes",
679 "http",
680 "pin-project-lite",
681 ]
682
683 [[package]]
636 684 name = "httparse"
637 685 version = "1.8.0"
638 686 source = "registry+https://github.com/rust-lang/crates.io-index"
639 687 checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
640 688
641 689 [[package]]
690 name = "httpdate"
691 version = "1.0.3"
692 source = "registry+https://github.com/rust-lang/crates.io-index"
693 checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
694
695 [[package]]
696 name = "hyper"
697 version = "0.14.27"
698 source = "registry+https://github.com/rust-lang/crates.io-index"
699 checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
700 dependencies = [
701 "bytes",
702 "futures-channel",
703 "futures-core",
704 "futures-util",
705 "h2",
706 "http",
707 "http-body",
708 "httparse",
709 "httpdate",
710 "itoa",
711 "pin-project-lite",
712 "socket2 0.4.9",
713 "tokio",
714 "tower-service",
715 "tracing",
716 "want",
717 ]
718
719 [[package]]
720 name = "hyper-tls"
721 version = "0.5.0"
722 source = "registry+https://github.com/rust-lang/crates.io-index"
723 checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
724 dependencies = [
725 "bytes",
726 "hyper",
727 "native-tls",
728 "tokio",
729 "tokio-native-tls",
730 ]
731
732 [[package]]
642 733 name = "iana-time-zone"
643 734 version = "0.1.57"
644 735 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -673,15 +764,31 @@ dependencies = [
673 764
674 765 [[package]]
675 766 name = "indexmap"
767 version = "1.9.3"
768 source = "registry+https://github.com/rust-lang/crates.io-index"
769 checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
770 dependencies = [
771 "autocfg",
772 "hashbrown 0.12.3",
773 ]
774
775 [[package]]
776 name = "indexmap"
676 777 version = "2.0.0"
677 778 source = "registry+https://github.com/rust-lang/crates.io-index"
678 779 checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
679 780 dependencies = [
680 781 "equivalent",
681 "hashbrown",
782 "hashbrown 0.14.0",
682 783 ]
683 784
684 785 [[package]]
786 name = "ipnet"
787 version = "2.8.0"
788 source = "registry+https://github.com/rust-lang/crates.io-index"
789 checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
790
791 [[package]]
685 792 name = "itertools"
686 793 version = "0.10.5"
687 794 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -838,6 +945,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
838 945 checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
839 946
840 947 [[package]]
948 name = "mime"
949 version = "0.3.17"
950 source = "registry+https://github.com/rust-lang/crates.io-index"
951 checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
952
953 [[package]]
841 954 name = "minimal-lexical"
842 955 version = "0.2.1"
843 956 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1211,6 +1324,43 @@ dependencies = [
1211 1324 ]
1212 1325
1213 1326 [[package]]
1327 name = "reqwest"
1328 version = "0.11.20"
1329 source = "registry+https://github.com/rust-lang/crates.io-index"
1330 checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
1331 dependencies = [
1332 "base64 0.21.3",
1333 "bytes",
1334 "encoding_rs",
1335 "futures-core",
1336 "futures-util",
1337 "h2",
1338 "http",
1339 "http-body",
1340 "hyper",
1341 "hyper-tls",
1342 "ipnet",
1343 "js-sys",
1344 "log",
1345 "mime",
1346 "native-tls",
1347 "once_cell",
1348 "percent-encoding",
1349 "pin-project-lite",
1350 "serde",
1351 "serde_json",
1352 "serde_urlencoded",
1353 "tokio",
1354 "tokio-native-tls",
1355 "tower-service",
1356 "url",
1357 "wasm-bindgen",
1358 "wasm-bindgen-futures",
1359 "web-sys",
1360 "winreg",
1361 ]
1362
1363 [[package]]
1214 1364 name = "ring"
1215 1365 version = "0.16.20"
1216 1366 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1241,6 +1391,7 @@ dependencies = [
1241 1391 "pkcs1",
1242 1392 "pkcs8",
1243 1393 "rand_core",
1394 "sha2",
1244 1395 "signature",
1245 1396 "spki",
1246 1397 "subtle",
@@ -1351,6 +1502,18 @@ dependencies = [
1351 1502 ]
1352 1503
1353 1504 [[package]]
1505 name = "serde_urlencoded"
1506 version = "0.7.1"
1507 source = "registry+https://github.com/rust-lang/crates.io-index"
1508 checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1509 dependencies = [
1510 "form_urlencoded",
1511 "itoa",
1512 "ryu",
1513 "serde",
1514 ]
1515
1516 [[package]]
1354 1517 name = "sha1"
1355 1518 version = "0.10.5"
1356 1519 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1429,6 +1592,16 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
1429 1592
1430 1593 [[package]]
1431 1594 name = "socket2"
1595 version = "0.4.9"
1596 source = "registry+https://github.com/rust-lang/crates.io-index"
1597 checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
1598 dependencies = [
1599 "libc",
1600 "winapi",
1601 ]
1602
1603 [[package]]
1604 name = "socket2"
1432 1605 version = "0.5.3"
1433 1606 source = "registry+https://github.com/rust-lang/crates.io-index"
1434 1607 checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
@@ -1509,7 +1682,7 @@ dependencies = [
1509 1682 "futures-util",
1510 1683 "hashlink",
1511 1684 "hex",
1512 "indexmap",
1685 "indexmap 2.0.0",
1513 1686 "log",
1514 1687 "memchr",
1515 1688 "native-tls",
@@ -1822,7 +1995,7 @@ dependencies = [
1822 1995 "parking_lot",
1823 1996 "pin-project-lite",
1824 1997 "signal-hook-registry",
1825 "socket2",
1998 "socket2 0.5.3",
1826 1999 "tokio-macros",
1827 2000 "windows-sys",
1828 2001 ]
@@ -1839,6 +2012,16 @@ dependencies = [
1839 2012 ]
1840 2013
1841 2014 [[package]]
2015 name = "tokio-native-tls"
2016 version = "0.3.1"
2017 source = "registry+https://github.com/rust-lang/crates.io-index"
2018 checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2019 dependencies = [
2020 "native-tls",
2021 "tokio",
2022 ]
2023
2024 [[package]]
1842 2025 name = "tokio-stream"
1843 2026 version = "0.1.14"
1844 2027 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1862,6 +2045,20 @@ dependencies = [
1862 2045 ]
1863 2046
1864 2047 [[package]]
2048 name = "tokio-util"
2049 version = "0.7.8"
2050 source = "registry+https://github.com/rust-lang/crates.io-index"
2051 checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
2052 dependencies = [
2053 "bytes",
2054 "futures-core",
2055 "futures-sink",
2056 "pin-project-lite",
2057 "tokio",
2058 "tracing",
2059 ]
2060
2061 [[package]]
1865 2062 name = "toml"
1866 2063 version = "0.7.6"
1867 2064 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1888,7 +2085,7 @@ version = "0.19.14"
1888 2085 source = "registry+https://github.com/rust-lang/crates.io-index"
1889 2086 checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
1890 2087 dependencies = [
1891 "indexmap",
2088 "indexmap 2.0.0",
1892 2089 "serde",
1893 2090 "serde_spanned",
1894 2091 "toml_datetime",
@@ -1896,6 +2093,12 @@ dependencies = [
1896 2093 ]
1897 2094
1898 2095 [[package]]
2096 name = "tower-service"
2097 version = "0.3.2"
2098 source = "registry+https://github.com/rust-lang/crates.io-index"
2099 checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
2100
2101 [[package]]
1899 2102 name = "tracing"
1900 2103 version = "0.1.37"
1901 2104 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1955,6 +2158,12 @@ dependencies = [
1955 2158 ]
1956 2159
1957 2160 [[package]]
2161 name = "try-lock"
2162 version = "0.2.4"
2163 source = "registry+https://github.com/rust-lang/crates.io-index"
2164 checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
2165
2166 [[package]]
1958 2167 name = "tungstenite"
1959 2168 version = "0.20.0"
1960 2169 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2054,6 +2263,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2054 2263 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
2055 2264
2056 2265 [[package]]
2266 name = "want"
2267 version = "0.3.1"
2268 source = "registry+https://github.com/rust-lang/crates.io-index"
2269 checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
2270 dependencies = [
2271 "try-lock",
2272 ]
2273
2274 [[package]]
2057 2275 name = "wasi"
2058 2276 version = "0.10.0+wasi-snapshot-preview1"
2059 2277 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2091,6 +2309,18 @@ dependencies = [
2091 2309 ]
2092 2310
2093 2311 [[package]]
2312 name = "wasm-bindgen-futures"
2313 version = "0.4.37"
2314 source = "registry+https://github.com/rust-lang/crates.io-index"
2315 checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
2316 dependencies = [
2317 "cfg-if",
2318 "js-sys",
2319 "wasm-bindgen",
2320 "web-sys",
2321 ]
2322
2323 [[package]]
2094 2324 name = "wasm-bindgen-macro"
2095 2325 version = "0.2.87"
2096 2326 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2242,6 +2472,16 @@ dependencies = [
2242 2472 ]
2243 2473
2244 2474 [[package]]
2475 name = "winreg"
2476 version = "0.50.0"
2477 source = "registry+https://github.com/rust-lang/crates.io-index"
2478 checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
2479 dependencies = [
2480 "cfg-if",
2481 "windows-sys",
2482 ]
2483
2484 [[package]]
2245 2485 name = "zeroize"
2246 2486 version = "1.6.0"
2247 2487 source = "registry+https://github.com/rust-lang/crates.io-index"

Cargo.toml

View file
@@ -15,6 +15,9 @@ serde_json = "1.0"
15 15 tracing-subscriber = "0.3"
16 16 jsonwebtoken = { version = "*", features = ["use_pem"]}
17 17 log = "*"
18 rand = "*"
19 rsa = {version = "*", features = ["sha2"]}
20 reqwest = "*"
18 21
19 22 toml = { version = "0.7" }
20 23

src/authentication.rs

View file
@@ -1,6 +1,5 @@
1 1 use std::{error::Error, time::SystemTime};
2 2
3 use chrono::Duration;
4 3 use jsonwebtoken::{encode, Algorithm, EncodingKey};
5 4 use serde::{Deserialize, Serialize};
6 5 use tokio::{fs::File, io::AsyncReadExt};

src/backend/git.rs

View file
@@ -5,6 +5,8 @@ use std::error::Error;
5 5 use std::path::{Path, PathBuf};
6 6 use thiserror::Error;
7 7
8 use crate::messages::Authenticated;
9 use crate::model::instance::Instance;
8 10 use crate::model::repository::{
9 11 Commit, RepositoryObjectType, RepositoryTreeEntry, RepositoryVisibility,
10 12 };
@@ -212,8 +214,19 @@ impl GitBackend {
212 214 impl RepositoryBackend for GitBackend {
213 215 async fn create_repository(
214 216 &mut self,
215 request: &CreateRepositoryRequest,
217 raw_request: &Authenticated<CreateRepositoryRequest>,
216 218 ) -> Result<CreateRepositoryResponse, Box<dyn Error + Send>> {
219 let request = raw_request.inner().await;
220
221 let public_key = public_key(&Instance {
222 url: String::from("giterated.dev"),
223 })
224 .await
225 .unwrap();
226
227 assert!(matches!(raw_request.validate(public_key).await, Ok(())));
228 info!("Request was valid!");
229
217 230 // Check if repository already exists in the database
218 231 if let Ok(_repository) = self
219 232 .find_by_instance_username_name(
@@ -465,3 +478,12 @@ impl IssuesBackend for GitBackend {
465 478 todo!()
466 479 }
467 480 }
481
482 async fn public_key(instance: &Instance) -> Result<String, Box<dyn Error>> {
483 let key = reqwest::get(format!("https://{}/.giterated/pubkey.pem", instance.url))
484 .await?
485 .text()
486 .await?;
487
488 Ok(key)
489 }

src/backend/mod.rs

View file
@@ -16,6 +16,7 @@ use crate::{
16 16 UserBioRequest, UserBioResponse, UserDisplayImageRequest, UserDisplayImageResponse,
17 17 UserDisplayNameRequest, UserDisplayNameResponse,
18 18 },
19 Authenticated,
19 20 },
20 21 model::repository::RepositoryView,
21 22 };
@@ -24,7 +25,7 @@ use crate::{
24 25 pub trait RepositoryBackend: IssuesBackend {
25 26 async fn create_repository(
26 27 &mut self,
27 request: &CreateRepositoryRequest,
28 request: &Authenticated<CreateRepositoryRequest>,
28 29 ) -> Result<CreateRepositoryResponse, Box<dyn Error + Send>>;
29 30 async fn repository_info(
30 31 &mut self,

src/connection.rs

View file
@@ -17,6 +17,7 @@ use crate::{
17 17 handshake::{HandshakeFinalize, HandshakeMessage, HandshakeResponse},
18 18 listener::Listeners,
19 19 messages::{
20 authentication::{AuthenticationMessage, AuthenticationRequest},
20 21 repository::{
21 22 RepositoryMessage, RepositoryMessageKind, RepositoryRequest, RepositoryResponse,
22 23 },
@@ -179,6 +180,7 @@ pub async fn connection_worker(
179 180 .unwrap();
180 181 }
181 182 }
183 continue;
182 184 } else {
183 185 // This message is targeting this instance
184 186 match &repository.command {
@@ -210,6 +212,8 @@ pub async fn connection_worker(
210 212 ))
211 213 .await
212 214 .unwrap();
215
216 continue;
213 217 }
214 218 RepositoryRequest::RepositoryFileInspect(request) => {
215 219 let mut backend = backend.lock().await;
@@ -240,6 +244,7 @@ pub async fn connection_worker(
240 244 ))
241 245 .await
242 246 .unwrap();
247 continue;
243 248 }
244 249 RepositoryRequest::RepositoryInfo(request) => {
245 250 let mut backend = backend.lock().await;
@@ -268,6 +273,7 @@ pub async fn connection_worker(
268 273 ))
269 274 .await
270 275 .unwrap();
276 continue;
271 277 }
272 278 RepositoryRequest::IssuesCount(request) => {
273 279 let mut backend = backend.lock().await;
@@ -296,6 +302,7 @@ pub async fn connection_worker(
296 302 ))
297 303 .await
298 304 .unwrap();
305 continue;
299 306 }
300 307 RepositoryRequest::IssueLabels(request) => {
301 308 let mut backend = backend.lock().await;
@@ -323,6 +330,7 @@ pub async fn connection_worker(
323 330 ))
324 331 .await
325 332 .unwrap();
333 continue;
326 334 }
327 335 RepositoryRequest::Issues(request) => {
328 336 let mut backend = backend.lock().await;
@@ -351,6 +359,7 @@ pub async fn connection_worker(
351 359 ))
352 360 .await
353 361 .unwrap();
362 continue;
354 363 }
355 364 },
356 365 RepositoryMessageKind::Response(_response) => {
@@ -359,6 +368,31 @@ pub async fn connection_worker(
359 368 }
360 369 }
361 370 }
371
372 if let MessageKind::Authentication(authentication) = &message {
373 match authentication {
374 AuthenticationMessage::Request(request) => match request {
375 AuthenticationRequest::AuthenticationToken(token) => {
376 let mut granter = auth_granter.lock().await;
377
378 let response = granter.token_request(token.clone()).await.unwrap();
379 drop(granter);
380
381 socket
382 .send(Message::Binary(
383 serde_json::to_vec(&MessageKind::Authentication(
384 AuthenticationMessage::Response(crate::messages::authentication::AuthenticationResponse::AuthenticationToken(response))
385 ))
386 .unwrap(),
387 ))
388 .await
389 .unwrap();
390 continue;
391 }
392 },
393 AuthenticationMessage::Response(_) => unreachable!(),
394 }
395 }
362 396 }
363 397
364 398 info!("Connection closed");

src/main.rs

View file
@@ -38,9 +38,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
38 38 .database(config["postgres"]["database"].as_str().unwrap())
39 39 .username(config["postgres"]["user"].as_str().unwrap())
40 40 .password(config["postgres"]["password"].as_str().unwrap())
41 .log_statements(log::LevelFilter::Off)
42 .to_owned();
41 .log_statements(log::LevelFilter::Off);
43 42 let db_pool = PgPool::connect_with(db_conn_options).await?;
43 info!("Connected");
44 44
45 45 let repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>> = Arc::new(Mutex::new({
46 46 let foo: GitBackend = GitBackend {
@@ -54,8 +54,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
54 54 config: config.clone(),
55 55 }));
56 56
57 info!("Connected");
58
57 59 loop {
58 60 let stream = accept_stream(&mut listener).await;
61 info!("Connected");
59 62
60 63 let (stream, address) = match stream {
61 64 Ok(stream) => stream,

src/messages/mod.rs

View file
@@ -1,3 +1,12 @@
1 use std::{error::Error, fmt::Debug};
2
3 use rsa::{
4 pkcs8::{DecodePrivateKey, DecodePublicKey},
5 pss::{Signature, SigningKey, VerifyingKey},
6 sha2::Sha256,
7 signature::{RandomizedSigner, SignatureEncoding, Verifier},
8 RsaPrivateKey, RsaPublicKey,
9 };
1 10 use serde::{Deserialize, Serialize};
2 11
3 12 use crate::handshake::HandshakeMessage;
@@ -15,3 +24,76 @@ pub enum MessageKind {
15 24 Repository(RepositoryMessage),
16 25 Authentication(AuthenticationMessage),
17 26 }
27
28 /// An authenticated message.
29 ///
30 /// Includes the message, with a digest generated with
31 /// our private key.
32 #[derive(Serialize, Deserialize)]
33 pub struct Authenticated<T: Serialize> {
34 #[serde(flatten)]
35 message: T,
36 token: String,
37 digest: Vec<u8>,
38 }
39
40 impl<T> Clone for Authenticated<T>
41 where
42 T: Clone + Serialize,
43 {
44 fn clone(&self) -> Self {
45 Self {
46 message: self.message.clone(),
47 token: self.token.clone(),
48 digest: self.digest.clone(),
49 }
50 }
51 }
52
53 impl<T> Debug for Authenticated<T>
54 where
55 T: Debug + Serialize,
56 {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 f.debug_struct("Authenticated")
59 .field("message", &self.message)
60 .field("token", &self.token)
61 .field("digest", &self.digest)
62 .finish()
63 }
64 }
65
66 impl<T: Serialize> Authenticated<T> {
67 pub fn new(message: T, token: String, private_key: String) -> Result<Self, Box<dyn Error>> {
68 let mut rng = rand::thread_rng();
69
70 let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key)?;
71 let signing_key = SigningKey::<Sha256>::new(private_key);
72
73 let message_json = serde_json::to_vec(&message)?;
74
75 let signature = signing_key.sign_with_rng(&mut rng, &message_json);
76
77 Ok(Self {
78 message,
79 token,
80 digest: signature.to_vec(),
81 })
82 }
83
84 pub async fn inner(&self) -> &T {
85 &self.message
86 }
87
88 pub async fn validate(&self, key: String) -> Result<(), Box<dyn Error>> {
89 let public_key = RsaPublicKey::from_public_key_pem(&key)?;
90
91 let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key);
92
93 let message_json = serde_json::to_vec(&self.message)?;
94
95 verifying_key.verify(&message_json, &Signature::try_from(self.digest.as_ref())?)?;
96
97 Ok(())
98 }
99 }

src/messages/repository.rs

View file
@@ -6,6 +6,8 @@ use crate::model::{
6 6 user::User,
7 7 };
8 8
9 use super::Authenticated;
10
9 11 #[derive(Clone, Serialize, Deserialize)]
10 12 pub struct RepositoryMessage {
11 13 pub target: Repository,
@@ -20,7 +22,7 @@ pub enum RepositoryMessageKind {
20 22
21 23 #[derive(Clone, Serialize, Deserialize)]
22 24 pub enum RepositoryRequest {
23 CreateRepository(CreateRepositoryRequest),
25 CreateRepository(Authenticated<CreateRepositoryRequest>),
24 26 RepositoryFileInspect(RepositoryFileInspectRequest),
25 27 RepositoryInfo(RepositoryInfoRequest),
26 28 IssuesCount(RepositoryIssuesCountRequest),