diff --git a/giterated-daemon/src/backend/user.rs b/giterated-daemon/src/backend/user.rs index d09c657..dda7da2 100644 --- a/giterated-daemon/src/backend/user.rs +++ b/giterated-daemon/src/backend/user.rs @@ -5,7 +5,6 @@ use anyhow::Error; use aes_gcm::{aead::Aead, AeadCore, Aes256Gcm, Key, KeyInit}; use argon2::{password_hash::SaltString, Argon2, PasswordHasher}; use base64::{engine::general_purpose::STANDARD, Engine as _}; -use futures_util::StreamExt; use giterated_models::{ messages::{ authentication::{ diff --git a/giterated-daemon/src/connection/authentication.rs b/giterated-daemon/src/connection/authentication.rs index 70f2c86..2372239 100644 --- a/giterated-daemon/src/connection/authentication.rs +++ b/giterated-daemon/src/connection/authentication.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use anyhow::Error; use thiserror::Error; use tokio::{fs::File, io::AsyncReadExt}; @@ -7,7 +5,8 @@ use tokio::{fs::File, io::AsyncReadExt}; use crate::message::{AuthenticatedInstance, Message, MessageHandler, NetworkMessage, State}; use giterated_models::{ messages::authentication::{ - AuthenticationTokenRequest, RegisterAccountRequest, TokenExtensionRequest, AuthenticationTokenResponse, + AuthenticationTokenRequest, AuthenticationTokenResponse, RegisterAccountRequest, + TokenExtensionRequest, }, model::authenticated::InstanceAuthenticator, }; @@ -20,21 +19,21 @@ pub async fn authentication_handle( state: &ConnectionState, ) -> Result { match message_type { - "&giterated_models::messages::authentication::RegisterAccountRequest" => { + "giterated_models::messages::authentication::RegisterAccountRequest" => { register_account_request .handle_message(&message, state) .await?; Ok(true) } - "&giterated_models::messages::authentication::AuthenticationTokenRequest" => { + "giterated_models::messages::authentication::AuthenticationTokenRequest" => { authentication_token_request .handle_message(&message, state) .await?; Ok(true) } - "&giterated_models::messages::authentication::TokenExtensionRequest" => { + "giterated_models::messages::authentication::TokenExtensionRequest" => { token_extension_request .handle_message(&message, state) .await?; @@ -83,14 +82,22 @@ async fn authentication_token_request( let connection = connections.get_or_open(&request.instance).unwrap(); let private_key = { - let mut file = File::open(connection_state.config["giterated"]["keys"]["private"].as_str().unwrap()).await.unwrap(); + let mut file = File::open( + connection_state.config["giterated"]["keys"]["private"] + .as_str() + .unwrap(), + ) + .await + .unwrap(); let mut key = String::new(); file.read_to_string(&mut key).await.unwrap(); - + key }; + info!("Our private key: {}", private_key); + let authenticator = InstanceAuthenticator { instance: connection_state.instance.clone(), private_key, @@ -99,10 +106,14 @@ async fn authentication_token_request( let response = giterated_api::request::request_local(request) .authenticate(authenticator) .execute_expect::(&connection) - .await.unwrap(); + .await + .unwrap(); drop(connection); - connection_state.send(response).await.map_err(|e| AuthenticationConnectionError::Sending(e))?; + connection_state + .send(response) + .await + .map_err(|e| AuthenticationConnectionError::Sending(e))?; return Ok(()); } @@ -159,12 +170,3 @@ pub enum AuthenticationConnectionError { #[error("error issuing token")] TokenIssuance(Error), } - -async fn private_key(path: &str) -> Vec { - let mut file = File::open(path).await.unwrap(); - - let mut key = vec![]; - file.read_to_end(&mut key).await.unwrap(); - - key -} diff --git a/giterated-daemon/src/connection/repository.rs b/giterated-daemon/src/connection/repository.rs index 2a37637..8a872e7 100644 --- a/giterated-daemon/src/connection/repository.rs +++ b/giterated-daemon/src/connection/repository.rs @@ -17,34 +17,34 @@ pub async fn repository_handle( state: &ConnectionState, ) -> Result { match message_type { - "&giterated_models::messages::repository::RepositoryCreateRequest" => { + "giterated_models::messages::repository::RepositoryCreateRequest" => { create_repository.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::repository::RepositoryFileInspectRequest" => { + "giterated_models::messages::repository::RepositoryFileInspectRequest" => { repository_file_inspect .handle_message(&message, state) .await?; Ok(true) } - "&giterated_models::messages::repository::RepositoryInfoRequest" => { + "giterated_models::messages::repository::RepositoryInfoRequest" => { repository_info.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::repository::RepositoryIssuesCountRequest" => { + "giterated_models::messages::repository::RepositoryIssuesCountRequest" => { issues_count.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::repository::RepositoryIssueLabelsRequest" => { + "giterated_models::messages::repository::RepositoryIssueLabelsRequest" => { issue_labels.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::repository::RepositoryIssuesRequest" => { + "giterated_models::messages::repository::RepositoryIssuesRequest" => { issues.handle_message(&message, state).await?; Ok(true) diff --git a/giterated-daemon/src/connection/user.rs b/giterated-daemon/src/connection/user.rs index 2d1cb5e..c3b5691 100644 --- a/giterated-daemon/src/connection/user.rs +++ b/giterated-daemon/src/connection/user.rs @@ -18,32 +18,32 @@ pub async fn user_handle( state: &ConnectionState, ) -> Result { match message_type { - "&giterated_models::messages::user::UserDisplayNameRequest" => { + "giterated_models::messages::user::UserDisplayNameRequest" => { display_name.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::user::UserDisplayImageRequest" => { + "giterated_models::messages::user::UserDisplayImageRequest" => { display_image.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::user::UserBioRequest" => { + "giterated_models::messages::user::UserBioRequest" => { bio.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::user::UserRepositoriesRequest" => { + "giterated_models::messages::user::UserRepositoriesRequest" => { repositories.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::user::UserSettingsRequest" => { + "giterated_models::messages::user::UserSettingsRequest" => { user_settings.handle_message(&message, state).await?; Ok(true) } - "&giterated_models::messages::user::UserWriteSettingsRequest" => { + "giterated_models::messages::user::UserWriteSettingsRequest" => { write_user_settings.handle_message(&message, state).await?; Ok(true) diff --git a/giterated-daemon/src/main.rs b/giterated-daemon/src/main.rs index a3c4e75..eb26a28 100644 --- a/giterated-daemon/src/main.rs +++ b/giterated-daemon/src/main.rs @@ -115,7 +115,7 @@ async fn main() -> Result<(), Error> { token_granter.clone(), settings.clone(), address, - Instance::from_str("giterated.dev").unwrap(), + Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap(), instance_connections.clone(), config.clone(), )), diff --git a/giterated-daemon/src/message.rs b/giterated-daemon/src/message.rs index ddb48e8..b1434b1 100644 --- a/giterated-daemon/src/message.rs +++ b/giterated-daemon/src/message.rs @@ -9,7 +9,7 @@ use giterated_models::model::{ }; use jsonwebtoken::{decode, Algorithm, DecodingKey, TokenData, Validation}; use rsa::{ - pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, + pkcs1::DecodeRsaPublicKey, pss::{Signature, VerifyingKey}, sha2::Sha256, signature::Verifier, @@ -110,6 +110,8 @@ impl FromMessage for AuthenticatedInstance { let message: AuthenticatedPayload = serde_json::from_slice(&network_message).map_err(|e| Error::from(e))?; + info!("Authenticated payload: {:?}", message); + let (instance, signature) = message .source .iter() @@ -128,6 +130,10 @@ impl FromMessage for AuthenticatedInstance { // TODO: Instance authentication error .ok_or_else(|| UserAuthenticationError::Missing)?; + info!("Instance: {}", instance.clone().to_string()); + + info!("Instance public key: {}", state.public_key(instance).await?); + let public_key = RsaPublicKey::from_pkcs1_pem(&state.public_key(instance).await?).unwrap(); let verifying_key: VerifyingKey = VerifyingKey::new(public_key); diff --git a/giterated-models/src/messages/authentication.rs b/giterated-models/src/messages/authentication.rs index f2c488b..7875375 100644 --- a/giterated-models/src/messages/authentication.rs +++ b/giterated-models/src/messages/authentication.rs @@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::model::{authenticated::UserAuthenticationToken, instance::Instance}; +use super::MessageTarget; + /// An account registration request. /// /// # Authentication @@ -37,6 +39,12 @@ pub struct AuthenticationTokenRequest { pub password: String, } +impl MessageTarget for AuthenticationTokenRequest { + fn target(&self) -> Option { + Some(self.instance.clone()) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AuthenticationTokenResponse { pub token: UserAuthenticationToken, @@ -57,6 +65,13 @@ pub struct TokenExtensionRequest { pub token: UserAuthenticationToken, } +impl MessageTarget for TokenExtensionRequest { + fn target(&self) -> Option { + // todo! + None + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TokenExtensionResponse { pub new_token: Option, diff --git a/giterated-models/src/messages/discovery.rs b/giterated-models/src/messages/discovery.rs index 3b4387d..75a0456 100644 --- a/giterated-models/src/messages/discovery.rs +++ b/giterated-models/src/messages/discovery.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::model::discovery::DiscoveryItem; +use super::MessageTarget; + #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct DiscoveryOffer { pub earliest: DateTime, @@ -15,6 +17,12 @@ pub struct DiscoveryRequest { pub hashes: Vec, } +impl MessageTarget for DiscoveryRequest { + fn target(&self) -> Option { + None + } +} + #[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct Discoveries { pub discoveries: Vec, diff --git a/giterated-models/src/messages/mod.rs b/giterated-models/src/messages/mod.rs index bc9f449..c2f2506 100644 --- a/giterated-models/src/messages/mod.rs +++ b/giterated-models/src/messages/mod.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::Debug; -use crate::model::user::User; +use crate::model::{instance::Instance, user::User}; pub mod authentication; pub mod discovery; @@ -18,3 +18,9 @@ pub enum ErrorMessage { #[error("internal error: shutdown")] Shutdown, } + +pub trait MessageTarget { + fn target(&self) -> Option { + None + } +} diff --git a/giterated-models/src/messages/repository.rs b/giterated-models/src/messages/repository.rs index 0b2597d..8a9f64f 100644 --- a/giterated-models/src/messages/repository.rs +++ b/giterated-models/src/messages/repository.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use crate::model::instance::Instance; use crate::model::repository::RepositoryVisibility; use crate::model::settings::Setting; use crate::model::{ @@ -10,6 +11,8 @@ use crate::model::{ user::User, }; +use super::MessageTarget; + /// A request to create a repository. /// /// # Authentication @@ -25,6 +28,7 @@ use crate::model::{ /// - Potential User permissions checks #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryCreateRequest { + pub instance: Option, pub name: String, pub description: Option, pub visibility: RepositoryVisibility, @@ -32,6 +36,12 @@ pub struct RepositoryCreateRequest { pub owner: User, } +impl MessageTarget for RepositoryCreateRequest { + fn target(&self) -> Option { + self.instance.clone() + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryCreateResponse; @@ -46,9 +56,16 @@ pub struct RepositoryCreateResponse; /// - Potential User permissions checks #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryFileInspectRequest { + pub repository: Repository, pub path: RepositoryTreeEntry, } +impl MessageTarget for RepositoryFileInspectRequest { + fn target(&self) -> Option { + Some(self.repository.instance.clone()) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub enum RepositoryFileInspectionResponse { File { @@ -75,6 +92,8 @@ pub enum RepositoryFileInspectionResponse { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssuesCountRequest; +impl MessageTarget for RepositoryIssuesCountRequest {} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssuesCountResponse { pub count: u64, @@ -92,6 +111,8 @@ pub struct RepositoryIssuesCountResponse { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssueLabelsRequest; +impl MessageTarget for RepositoryIssueLabelsRequest {} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssueLabelsResponse { pub labels: Vec, @@ -115,6 +136,8 @@ pub struct IssueLabel { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssuesRequest; +impl MessageTarget for RepositoryIssuesRequest {} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssuesResponse { pub issues: Vec, @@ -149,11 +172,23 @@ pub struct RepositoryInfoRequest { pub path: Option, } +impl MessageTarget for RepositoryInfoRequest { + fn target(&self) -> Option { + Some(self.repository.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct RepositorySettingsRequest { pub repository: Repository, } +impl MessageTarget for RepositorySettingsRequest { + fn target(&self) -> Option { + Some(self.repository.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Default, Deserialize)] pub struct RepositorySettingsResponse { pub settings: HashMap, @@ -177,6 +212,12 @@ pub struct RepositoryWriteSettingsRequest { pub settings: Vec<(String, String)>, } +impl MessageTarget for RepositoryWriteSettingsRequest { + fn target(&self) -> Option { + Some(self.repository.instance.clone()) + } +} + impl RepositoryWriteSettingsRequest { pub fn new(repository: impl ToOwned) -> Self { Self { diff --git a/giterated-models/src/messages/user.rs b/giterated-models/src/messages/user.rs index 5a5fe42..4a82e19 100644 --- a/giterated-models/src/messages/user.rs +++ b/giterated-models/src/messages/user.rs @@ -2,13 +2,23 @@ use std::collections::HashMap; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use crate::model::{repository::RepositorySummary, settings::Setting, user::User}; +use crate::model::{ + instance::Instance, repository::RepositorySummary, settings::Setting, user::User, +}; + +use super::MessageTarget; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserDisplayNameRequest { pub user: User, } +impl MessageTarget for UserDisplayNameRequest { + fn target(&self) -> Option { + Some(self.user.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserDisplayNameResponse { pub display_name: Option, @@ -19,6 +29,12 @@ pub struct UserDisplayImageRequest { pub user: User, } +impl MessageTarget for UserDisplayImageRequest { + fn target(&self) -> Option { + Some(self.user.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserDisplayImageResponse { pub image_url: Option, @@ -29,6 +45,12 @@ pub struct UserBioRequest { pub user: User, } +impl MessageTarget for UserBioRequest { + fn target(&self) -> Option { + Some(self.user.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserBioResponse { pub bio: Option, @@ -36,9 +58,16 @@ pub struct UserBioResponse { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserRepositoriesRequest { + pub instance: Instance, pub user: User, } +impl MessageTarget for UserRepositoriesRequest { + fn target(&self) -> Option { + Some(self.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserRepositoriesResponse { pub repositories: Vec, @@ -49,6 +78,12 @@ pub struct UserSettingsRequest { pub user: User, } +impl MessageTarget for UserSettingsRequest { + fn target(&self) -> Option { + Some(self.user.instance.clone()) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Default, Deserialize)] pub struct UserSettingsResponse { pub settings: HashMap, @@ -72,6 +107,12 @@ pub struct UserWriteSettingsRequest { pub settings: Vec<(String, String)>, } +impl MessageTarget for UserWriteSettingsRequest { + fn target(&self) -> Option { + Some(self.user.instance.clone()) + } +} + impl UserWriteSettingsRequest { pub fn new(user: impl ToOwned) -> Self { Self { diff --git a/giterated-models/src/model/authenticated.rs b/giterated-models/src/model/authenticated.rs index daf8b64..f44fe78 100644 --- a/giterated-models/src/model/authenticated.rs +++ b/giterated-models/src/model/authenticated.rs @@ -10,6 +10,8 @@ use rsa::{ use serde::{Deserialize, Serialize}; use tracing::info; +use crate::messages::MessageTarget; + use super::{instance::Instance, user::User}; #[derive(Debug, Serialize, Deserialize)] @@ -81,13 +83,13 @@ where } } -impl Authenticated { +impl Authenticated { pub fn new(message: T) -> Self { Self { source: vec![], message_type: type_name::().to_string(), + target_instance: message.target(), message, - target_instance: None, } } @@ -104,8 +106,8 @@ impl Authenticated { Self { source: vec![], message_type: type_name::().to_string(), + target_instance: message.target(), message, - target_instance: None, } }