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

ambee/giterated

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

Add all the user request handling

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨e3bda14

Showing ⁨⁨7⁩ changed files⁩ with ⁨⁨182⁩ insertions⁩ and ⁨⁨9⁩ deletions⁩

src/backend/discovery.rs

View file
@@ -81,7 +81,7 @@ impl DiscoveryBackend for GiteratedDiscoveryProtocol {
81 81 .await;
82 82
83 83 match result {
84 Ok(_) => {},
84 Ok(_) => {}
85 85 Err(err) => {
86 86 error!("Error inserting discovery. {:?}", err);
87 87 }
@@ -105,4 +105,4 @@ pub struct DiscoveriesRow {
105 105 discovery_time: DateTime<Utc>,
106 106 discovery_type: DiscoveryType,
107 107 discovery: String,
108 }
108 \ No newline at end of file
108 }

src/backend/git.rs

View file
@@ -1,14 +1,16 @@
1 1 use anyhow::Error;
2 2 use async_trait::async_trait;
3 use futures_util::StreamExt;
3 4 use git2::ObjectType;
4 use sqlx::PgPool;
5 use sqlx::{Either, PgPool};
5 6 use std::path::{Path, PathBuf};
6 7 use thiserror::Error;
7 8
8 9 use crate::messages::ValidatedUserAuthenticated;
9 10
11 use crate::model::instance::Instance;
10 12 use crate::model::repository::{
11 Commit, RepositoryObjectType, RepositoryTreeEntry, RepositoryVisibility,
13 Commit, Repository, RepositoryObjectType, RepositoryTreeEntry, RepositoryVisibility,
12 14 };
13 15 use crate::model::user::User;
14 16 use crate::{
@@ -29,6 +31,7 @@ use super::{IssuesBackend, RepositoryBackend};
29 31 /// Repository in the database
30 32 #[derive(Debug, sqlx::FromRow)]
31 33 pub struct GitRepository {
34 #[sqlx(try_from = "String")]
32 35 pub owner_user: User,
33 36 pub name: String,
34 37 pub description: Option<String>,
@@ -94,13 +97,19 @@ pub enum GitBackendError {
94 97 pub struct GitBackend {
95 98 pub pg_pool: PgPool,
96 99 pub repository_folder: String,
100 pub instance: Instance,
97 101 }
98 102
99 103 impl GitBackend {
100 pub fn new(pg_pool: &PgPool, repository_folder: &str) -> Self {
104 pub fn new(
105 pg_pool: &PgPool,
106 repository_folder: &str,
107 instance: impl ToOwned<Owned = Instance>,
108 ) -> Self {
101 109 Self {
102 110 pg_pool: pg_pool.clone(),
103 111 repository_folder: repository_folder.to_string(),
112 instance: instance.to_owned(),
104 113 }
105 114 }
106 115
@@ -442,6 +451,27 @@ impl RepositoryBackend for GitBackend {
442 451 ) -> Result<RepositoryFileInspectionResponse, Error> {
443 452 todo!()
444 453 }
454
455 async fn repositories_for_user(&mut self, user: &User) -> Result<Vec<Repository>, Error> {
456 let mut repositories = sqlx::query_as!(
457 GitRepository,
458 r#"SELECT visibility as "visibility: _", owner_user, name, description, default_branch FROM repositories WHERE owner_user = $1"#,
459 user.to_string()
460 )
461 .fetch_many(&self.pg_pool);
462
463 let mut result = vec![];
464
465 while let Some(Ok(Either::Right(repository))) = repositories.next().await {
466 result.push(Repository {
467 owner: repository.owner_user,
468 name: repository.name,
469 instance: self.instance.clone(),
470 });
471 }
472
473 Ok(result)
474 }
445 475 }
446 476
447 477 impl IssuesBackend for GitBackend {

src/backend/mod.rs

View file
@@ -25,7 +25,10 @@ use crate::{
25 25 },
26 26 ValidatedUserAuthenticated,
27 27 },
28 model::repository::{Repository, RepositoryView},
28 model::{
29 repository::{Repository, RepositoryView},
30 user::User,
31 },
29 32 };
30 33
31 34 #[async_trait]
@@ -42,6 +45,7 @@ pub trait RepositoryBackend: IssuesBackend {
42 45 &mut self,
43 46 request: &ValidatedUserAuthenticated<RepositoryFileInspectRequest>,
44 47 ) -> Result<RepositoryFileInspectionResponse, Error>;
48 async fn repositories_for_user(&mut self, user: &User) -> Result<Vec<Repository>, Error>;
45 49 }
46 50
47 51 pub trait IssuesBackend {

src/connection.rs

View file
@@ -27,6 +27,10 @@ use crate::{
27 27 repository::{
28 28 RepositoryMessage, RepositoryMessageKind, RepositoryRequest, RepositoryResponse,
29 29 },
30 user::{
31 UserMessage, UserMessageKind, UserMessageRequest, UserMessageResponse,
32 UserRepositoriesResponse,
33 },
30 34 MessageKind,
31 35 },
32 36 model::{
@@ -453,6 +457,126 @@ pub async fn connection_worker(
453 457
454 458 continue;
455 459 }
460
461 if let MessageKind::User(message) = &message {
462 match &message.message {
463 UserMessageKind::Request(request) => match request {
464 UserMessageRequest::DisplayName(request) => {
465 let mut user_backend = user_backend.lock().await;
466
467 let response = user_backend.display_name(request.clone()).await;
468
469 let response = match response {
470 Ok(response) => response,
471 Err(err) => {
472 error!("Error handling request: {:?}", err);
473 continue;
474 }
475 };
476 drop(user_backend);
477
478 let _result = send(
479 &mut socket,
480 MessageKind::User(UserMessage {
481 instance: message.instance.clone(),
482 message: UserMessageKind::Response(
483 UserMessageResponse::DisplayName(response),
484 ),
485 }),
486 )
487 .await;
488
489 continue;
490 }
491 UserMessageRequest::DisplayImage(request) => {
492 let mut user_backend = user_backend.lock().await;
493
494 let response = user_backend.display_image(request.clone()).await;
495
496 let response = match response {
497 Ok(response) => response,
498 Err(err) => {
499 error!("Error handling request: {:?}", err);
500 continue;
501 }
502 };
503 drop(user_backend);
504
505 let _result = send(
506 &mut socket,
507 MessageKind::User(UserMessage {
508 instance: message.instance.clone(),
509 message: UserMessageKind::Response(
510 UserMessageResponse::DisplayImage(response),
511 ),
512 }),
513 )
514 .await;
515
516 continue;
517 }
518 UserMessageRequest::Bio(request) => {
519 let mut user_backend = user_backend.lock().await;
520
521 let response = user_backend.bio(request.clone()).await;
522
523 let response = match response {
524 Ok(response) => response,
525 Err(err) => {
526 error!("Error handling request: {:?}", err);
527 continue;
528 }
529 };
530 drop(user_backend);
531
532 let _result = send(
533 &mut socket,
534 MessageKind::User(UserMessage {
535 instance: message.instance.clone(),
536 message: UserMessageKind::Response(UserMessageResponse::Bio(
537 response,
538 )),
539 }),
540 )
541 .await;
542
543 continue;
544 }
545 UserMessageRequest::Repositories(request) => {
546 let mut repository_backend = backend.lock().await;
547
548 let repositories = repository_backend
549 .repositories_for_user(&request.user)
550 .await;
551
552 let repositories = match repositories {
553 Ok(repositories) => repositories,
554 Err(err) => {
555 error!("Error handling request: {:?}", err);
556 continue;
557 }
558 };
559 drop(repository_backend);
560
561 let response = UserRepositoriesResponse { repositories };
562
563 let _result = send(
564 &mut socket,
565 MessageKind::User(UserMessage {
566 instance: message.instance.clone(),
567 message: UserMessageKind::Response(
568 UserMessageResponse::Repositories(response),
569 ),
570 }),
571 )
572 .await;
573
574 continue;
575 }
576 },
577 UserMessageKind::Response(_) => unreachable!(),
578 }
579 }
456 580 }
457 581
458 582 info!("Connection closed");
@@ -471,6 +595,7 @@ async fn send_and_get_listener(
471 595 MessageKind::Repository(repository) => (None, None, Some(repository.target.clone())),
472 596 MessageKind::Authentication(_) => todo!(),
473 597 MessageKind::Discovery(_) => todo!(),
598 MessageKind::User(user) => todo!(),
474 599 };
475 600
476 601 let target = match (&instance, &user, &repository) {

src/main.rs

View file
@@ -57,6 +57,7 @@ async fn main() -> Result<(), Error> {
57 57 .as_str()
58 58 .unwrap(),
59 59 ),
60 instance: Instance::from_str("giterated.dev").unwrap(),
60 61 }));
61 62
62 63 let token_granter = Arc::new(Mutex::new(AuthenticationTokenGranter {

src/messages/mod.rs

View file
@@ -18,7 +18,7 @@ use crate::{
18 18
19 19 use self::{
20 20 authentication::AuthenticationMessage, discovery::DiscoveryMessage,
21 repository::RepositoryMessage,
21 repository::RepositoryMessage, user::UserMessage,
22 22 };
23 23
24 24 pub mod authentication;
@@ -33,6 +33,7 @@ pub enum MessageKind {
33 33 Repository(RepositoryMessage),
34 34 Authentication(AuthenticationMessage),
35 35 Discovery(DiscoveryMessage),
36 User(UserMessage),
36 37 }
37 38
38 39 /// An authenticated message, where the instance is authenticating

src/messages/user.rs

View file
@@ -1,6 +1,6 @@
1 1 use serde::{Deserialize, Serialize};
2 2
3 use crate::model::{instance::Instance, user::User};
3 use crate::model::{instance::Instance, repository::Repository, user::User};
4 4
5 5 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
6 6 pub struct UserMessage {
@@ -19,13 +19,15 @@ pub enum UserMessageRequest {
19 19 DisplayName(UserDisplayNameRequest),
20 20 DisplayImage(UserDisplayImageRequest),
21 21 Bio(UserBioRequest),
22 Repositories(UserRepositoriesRequest),
22 23 }
23 24
24 25 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
25 26 pub enum UserMessageResponse {
26 DisplayName(UserDisplayImageResponse),
27 DisplayName(UserDisplayNameResponse),
27 28 DisplayImage(UserDisplayImageResponse),
28 29 Bio(UserBioResponse),
30 Repositories(UserRepositoriesResponse),
29 31 }
30 32
31 33 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
@@ -57,3 +59,13 @@ pub struct UserBioRequest {
57 59 pub struct UserBioResponse {
58 60 pub bio: Option<String>,
59 61 }
62
63 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
64 pub struct UserRepositoriesRequest {
65 pub user: User,
66 }
67
68 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
69 pub struct UserRepositoriesResponse {
70 pub repositories: Vec<Repository>,
71 }