From 206e64cd5b478a94cdbdebfde5b87dd36d92da77 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Wed, 29 May 2024 19:22:05 +0100 Subject: [PATCH] feat: Webhook query paths include forge alias This allows for more than one forge to be configured and for the webhook to correctly route incoming messages. --- crates/config/src/common.rs | 6 ++-- crates/config/src/forge_details.rs | 14 ++++---- crates/config/src/forge_name.rs | 10 +++--- crates/config/src/lib.rs | 2 +- crates/config/src/server.rs | 11 +++--- crates/config/src/tests/mod.rs | 28 +++++++-------- crates/forge-forgejo/src/lib.rs | 2 +- crates/forge/src/mock_forge.rs | 2 +- crates/forge/src/tests/mod.rs | 4 +-- crates/git/src/forge_like.rs | 2 +- crates/git/src/repo_details.rs | 8 ++--- crates/git/src/tests.rs | 6 ++-- crates/repo-actor/src/lib.rs | 2 +- crates/repo-actor/src/webhook.rs | 16 +++++---- crates/server/src/actors/server.rs | 20 ++++++----- crates/server/src/actors/webhook/router.rs | 40 +++++++++++++++------- crates/server/src/actors/webhook/server.rs | 26 ++++++++++---- 17 files changed, 119 insertions(+), 80 deletions(-) diff --git a/crates/config/src/common.rs b/crates/config/src/common.rs index 82375f3..fc3f5eb 100644 --- a/crates/config/src/common.rs +++ b/crates/config/src/common.rs @@ -1,5 +1,5 @@ use crate::{ - ApiToken, BranchName, ForgeDetails, ForgeName, ForgeType, Hostname, RepoAlias, RepoBranches, + ApiToken, BranchName, ForgeAlias, ForgeDetails, ForgeType, Hostname, RepoAlias, RepoBranches, RepoConfig, RepoConfigSource, RepoPath, User, }; @@ -25,8 +25,8 @@ pub fn hostname(n: u32) -> Hostname { Hostname::new(format!("hostname-{}", n)) } -pub fn forge_name(n: u32) -> ForgeName { - ForgeName::new(format!("forge-name-{}", n)) +pub fn forge_name(n: u32) -> ForgeAlias { + ForgeAlias::new(format!("forge-name-{}", n)) } pub fn branch_name(n: u32) -> BranchName { diff --git a/crates/config/src/forge_details.rs b/crates/config/src/forge_details.rs index 22d0e5b..c626f83 100644 --- a/crates/config/src/forge_details.rs +++ b/crates/config/src/forge_details.rs @@ -1,9 +1,9 @@ -use crate::{ApiToken, ForgeConfig, ForgeName, ForgeType, Hostname, User}; +use crate::{ApiToken, ForgeAlias, ForgeConfig, ForgeType, Hostname, User}; /// The derived information about a Forge, used to create interactions with it #[derive(Clone, Default, Debug, derive_more::Constructor, derive_with::With)] pub struct ForgeDetails { - forge_name: ForgeName, + forge_alias: ForgeAlias, forge_type: ForgeType, hostname: Hostname, user: User, @@ -12,8 +12,8 @@ pub struct ForgeDetails { // Private SSH Key Path } impl ForgeDetails { - pub const fn forge_name(&self) -> &ForgeName { - &self.forge_name + pub const fn forge_alias(&self) -> &ForgeAlias { + &self.forge_alias } pub const fn forge_type(&self) -> ForgeType { self.forge_type @@ -28,10 +28,10 @@ impl ForgeDetails { &self.token } } -impl From<(&ForgeName, &ForgeConfig)> for ForgeDetails { - fn from(forge: (&ForgeName, &ForgeConfig)) -> Self { +impl From<(&ForgeAlias, &ForgeConfig)> for ForgeDetails { + fn from(forge: (&ForgeAlias, &ForgeConfig)) -> Self { Self { - forge_name: forge.0.clone(), + forge_alias: forge.0.clone(), forge_type: forge.1.forge_type(), hostname: forge.1.hostname(), user: forge.1.user(), diff --git a/crates/config/src/forge_name.rs b/crates/config/src/forge_name.rs index b74406c..aa3c47e 100644 --- a/crates/config/src/forge_name.rs +++ b/crates/config/src/forge_name.rs @@ -1,10 +1,12 @@ use std::path::PathBuf; /// The name of a Forge to connect to -#[derive(Clone, Default, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Display)] -pub struct ForgeName(String); -impl From<&ForgeName> for PathBuf { - fn from(value: &ForgeName) -> Self { +#[derive( + Clone, Default, Debug, Hash, PartialEq, Eq, derive_more::Constructor, derive_more::Display, +)] +pub struct ForgeAlias(String); +impl From<&ForgeAlias> for PathBuf { + fn from(value: &ForgeAlias) -> Self { Self::from(&value.0) } } diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 133bcda..5477ed5 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -24,7 +24,7 @@ pub use api_token::ApiToken; pub use branch_name::BranchName; pub use forge_config::ForgeConfig; pub use forge_details::ForgeDetails; -pub use forge_name::ForgeName; +pub use forge_name::ForgeAlias; pub use forge_type::ForgeType; pub use git_dir::GitDir; pub use host_name::Hostname; diff --git a/crates/config/src/server.rs b/crates/config/src/server.rs index f3e3394..ccc692b 100644 --- a/crates/config/src/server.rs +++ b/crates/config/src/server.rs @@ -12,7 +12,7 @@ use std::{ use kxio::fs::FileSystem; use tracing::info; -use crate::{ForgeConfig, ForgeName}; +use crate::{ForgeAlias, ForgeConfig, RepoAlias}; #[derive(Debug, derive_more::From, derive_more::Display)] pub enum Error { @@ -43,10 +43,10 @@ impl ServerConfig { toml::from_str(&str).map_err(Into::into) } - pub fn forges(&self) -> impl Iterator { + pub fn forges(&self) -> impl Iterator { self.forge .iter() - .map(|(name, forge)| (ForgeName::new(name.clone()), forge)) + .map(|(alias, forge)| (ForgeAlias::new(alias.clone()), forge)) } pub const fn storage(&self) -> &ServerStorage { @@ -84,8 +84,9 @@ pub struct Webhook { url: String, } impl Webhook { - pub fn url(&self) -> WebhookUrl { - WebhookUrl(self.url.clone()) + pub fn url(&self, forge_alias: &ForgeAlias, repo_alias: &RepoAlias) -> WebhookUrl { + let base_url = &self.url; + WebhookUrl(format!("{base_url}/{forge_alias}/{repo_alias}")) } } diff --git a/crates/config/src/tests/mod.rs b/crates/config/src/tests/mod.rs index 263dd16..de4e729 100644 --- a/crates/config/src/tests/mod.rs +++ b/crates/config/src/tests/mod.rs @@ -252,7 +252,7 @@ mod forge_details { use secrecy::ExposeSecret; - use crate::{ApiToken, ForgeConfig, ForgeDetails, ForgeName, ForgeType, Hostname, User}; + use crate::{ApiToken, ForgeAlias, ForgeConfig, ForgeDetails, ForgeType, Hostname, User}; #[test] fn should_return_forge_name() { @@ -260,11 +260,11 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name.clone(), forge_type, hostname, user, token); - let result = forge_details.forge_name(); + let result = forge_details.forge_alias(); assert_eq!(result, &forge_name); } @@ -274,7 +274,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token); let result = forge_details.forge_type(); @@ -287,7 +287,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name, forge_type, hostname.clone(), user, token); @@ -301,7 +301,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user.clone(), token); @@ -315,7 +315,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token.clone()); @@ -329,7 +329,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_name = ForgeAlias::new("gamma".to_string()); let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token); let result = forge_details.with_hostname(Hostname::new("remotehost".to_string())); @@ -342,7 +342,7 @@ mod forge_details { let hostname = Hostname::new("localhost".to_string()); let user = User::new("bob".to_string()); let token = ApiToken::new("alpha".to_string().into()); - let forge_name = ForgeName::new("gamma".to_string()); + let forge_alias = ForgeAlias::new("gamma".to_string()); let forge_config = ForgeConfig::new( forge_type, "localhost".to_string(), @@ -351,9 +351,9 @@ mod forge_details { BTreeMap::new(), ); - let forge_details = ForgeDetails::from((&forge_name, &forge_config)); + let forge_details = ForgeDetails::from((&forge_alias, &forge_config)); - assert_eq!(forge_details.forge_name(), &forge_name); + assert_eq!(forge_details.forge_alias(), &forge_alias); assert_eq!(forge_details.hostname(), &hostname); assert_eq!(forge_details.user(), &user); assert_eq!(forge_details.token().expose_secret(), token.expose_secret()); @@ -362,13 +362,13 @@ mod forge_details { mod forge_name { use std::path::PathBuf; - use crate::ForgeName; + use crate::ForgeAlias; #[test] fn should_convert_to_pathbuf() { - let forge_name = ForgeName::new("alpha".to_string()); + let forge_alias = ForgeAlias::new("alpha".to_string()); - let pathbuf: PathBuf = (&forge_name).into(); + let pathbuf: PathBuf = (&forge_alias).into(); assert_eq!(pathbuf, PathBuf::new().join("alpha")); } diff --git a/crates/forge-forgejo/src/lib.rs b/crates/forge-forgejo/src/lib.rs index c80c752..c1437df 100644 --- a/crates/forge-forgejo/src/lib.rs +++ b/crates/forge-forgejo/src/lib.rs @@ -15,7 +15,7 @@ impl ForgeJo { } #[async_trait::async_trait] impl git::ForgeLike for ForgeJo { - fn name(&self) -> String { + fn forge_alias(&self) -> String { "forgejo".to_string() } diff --git a/crates/forge/src/mock_forge.rs b/crates/forge/src/mock_forge.rs index a5f211a..78b482f 100644 --- a/crates/forge/src/mock_forge.rs +++ b/crates/forge/src/mock_forge.rs @@ -13,7 +13,7 @@ impl MockForgeEnv { } #[async_trait::async_trait] impl git::ForgeLike for MockForgeEnv { - fn name(&self) -> String { + fn forge_alias(&self) -> String { "mock".to_string() } diff --git a/crates/forge/src/tests/mod.rs b/crates/forge/src/tests/mod.rs index 636f4fb..0488c5d 100644 --- a/crates/forge/src/tests/mod.rs +++ b/crates/forge/src/tests/mod.rs @@ -10,7 +10,7 @@ mod github; #[test] fn test_mock_name() { let forge = Forge::new_mock(); - assert_eq!(forge.name(), "mock"); + assert_eq!(forge.forge_alias(), "mock"); } #[test] @@ -30,5 +30,5 @@ fn test_forgejo_name() { config::GitDir::new(fs.base()), ); let forge = Forge::new_forgejo(repo_details, net); - assert_eq!(forge.name(), "forgejo"); + assert_eq!(forge.forge_alias(), "forgejo"); } diff --git a/crates/git/src/forge_like.rs b/crates/git/src/forge_like.rs index 46dd08b..b10b16d 100644 --- a/crates/git/src/forge_like.rs +++ b/crates/git/src/forge_like.rs @@ -2,7 +2,7 @@ use crate as git; #[async_trait::async_trait] pub trait ForgeLike { - fn name(&self) -> String; + fn forge_alias(&self) -> String; /// Checks the results of any (e.g. CI) status checks for the commit. async fn commit_status(&self, commit: &git::Commit) -> git::commit::Status; diff --git a/crates/git/src/repo_details.rs b/crates/git/src/repo_details.rs index f771fb9..d993bf7 100644 --- a/crates/git/src/repo_details.rs +++ b/crates/git/src/repo_details.rs @@ -1,5 +1,5 @@ use git_next_config::{ - BranchName, ForgeConfig, ForgeDetails, ForgeName, GitDir, RepoAlias, RepoConfig, RepoPath, + BranchName, ForgeAlias, ForgeConfig, ForgeDetails, GitDir, RepoAlias, RepoConfig, RepoPath, ServerRepoConfig, }; @@ -8,7 +8,7 @@ use super::{Generation, GitRemote}; /// The derived information about a repo, used to interact with it #[derive(Clone, Default, Debug, derive_more::Display, derive_with::With)] #[display("gen-{}:{}:{}/{}:{}@{}/{}@{}", generation, forge.forge_type(), - forge.forge_name(), repo_alias, forge.user(), forge.hostname(), repo_path, + forge.forge_alias(), repo_alias, forge.user(), forge.hostname(), repo_path, branch)] pub struct RepoDetails { pub generation: Generation, @@ -24,7 +24,7 @@ impl RepoDetails { generation: Generation, repo_alias: &RepoAlias, server_repo_config: &ServerRepoConfig, - forge_name: &ForgeName, + forge_alias: &ForgeAlias, forge_config: &ForgeConfig, gitdir: GitDir, ) -> Self { @@ -36,7 +36,7 @@ impl RepoDetails { branch: server_repo_config.branch(), gitdir, forge: ForgeDetails::new( - forge_name.clone(), + forge_alias.clone(), forge_config.forge_type(), forge_config.hostname(), forge_config.user(), diff --git a/crates/git/src/tests.rs b/crates/git/src/tests.rs index c75fb47..12674f7 100644 --- a/crates/git/src/tests.rs +++ b/crates/git/src/tests.rs @@ -92,7 +92,7 @@ mod repo_details { use std::{collections::BTreeMap, path::PathBuf}; use git_next_config::{ - ForgeConfig, ForgeName, ForgeType, GitDir, Hostname, RepoAlias, RepoPath, ServerRepoConfig, + ForgeAlias, ForgeConfig, ForgeType, GitDir, Hostname, RepoAlias, RepoPath, ServerRepoConfig, }; use secrecy::ExposeSecret; @@ -111,7 +111,7 @@ mod repo_details { None, None, ), - &ForgeName::new("default".to_string()), + &ForgeAlias::new("default".to_string()), &ForgeConfig::new( ForgeType::MockForge, "host".to_string(), @@ -140,7 +140,7 @@ mod repo_details { None, None, ), - &ForgeName::new("default".to_string()), + &ForgeAlias::new("default".to_string()), &ForgeConfig::new( ForgeType::MockForge, "host".to_string(), diff --git a/crates/repo-actor/src/lib.rs b/crates/repo-actor/src/lib.rs index 8ae8a08..b372733 100644 --- a/crates/repo-actor/src/lib.rs +++ b/crates/repo-actor/src/lib.rs @@ -20,7 +20,7 @@ use kxio::network::Network; use tracing::{debug, info, warn, Instrument}; #[derive(Debug, derive_more::Display)] -#[display("{}:{}:{}", generation, repo_details.forge.forge_name(), repo_details.repo_alias)] +#[display("{}:{}:{}", generation, repo_details.forge.forge_alias(), repo_details.repo_alias)] pub struct RepoActor { generation: git::Generation, message_token: MessageToken, diff --git a/crates/repo-actor/src/webhook.rs b/crates/repo-actor/src/webhook.rs index 3af2592..b57ecc4 100644 --- a/crates/repo-actor/src/webhook.rs +++ b/crates/repo-actor/src/webhook.rs @@ -1,7 +1,7 @@ use actix::prelude::*; use git_next_config::{ server::{Webhook, WebhookUrl}, - BranchName, RepoAlias, RepoBranches, + BranchName, ForgeAlias, RepoAlias, RepoBranches, }; use git_next_git as git; use kxio::network::{self, json}; @@ -75,7 +75,9 @@ pub async fn register( return; }; - let webhook_url = webhook.url(); + let forge_alias = repo_details.forge.forge_alias(); + let repo_alias = &repo_details.repo_alias; + let webhook_url = webhook.url(forge_alias, repo_alias); // remove any lingering webhooks for the same URL let existing_webhook_ids = find_existing_webhooks(&repo_details, &webhook_url, &net).await; for webhook_id in existing_webhook_ids { @@ -89,7 +91,6 @@ pub async fn register( let url = network::NetUrl::new(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" )); - let repo_alias = &repo_details.repo_alias; let headers = network::NetRequestHeaders::new().with("Content-Type", "application/json"); let authorisation = WebhookAuth::generate(); let body = json!({ @@ -98,7 +99,7 @@ pub async fn register( "branch_filter": format!("{{{},{},{}}}", repo_config.branches().main(), repo_config.branches().next(), repo_config.branches().dev()), "config": { "content_type": "json", - "url": format!("{}/{}", webhook_url.as_ref(), repo_alias), + "url": webhook_url.as_ref(), }, "events": [ "push" ], "type": "forgejo" @@ -156,7 +157,7 @@ async fn find_existing_webhooks( } for hook in list { if let Some(existing_url) = hook.config.get("url") { - if existing_url.starts_with(webhook_url.as_ref()) { + if existing_url == webhook_url.as_ref() { ids.push(hook.id()); } } @@ -312,12 +313,15 @@ struct HeadCommit { #[derive(Message, Debug, Clone, derive_more::Constructor)] #[rtype(result = "()")] pub struct WebhookMessage { - // forge // TODO: (#58) differentiate between multiple forges + forge_alias: ForgeAlias, repo_alias: RepoAlias, authorisation: WebhookAuth, body: Body, } impl WebhookMessage { + pub const fn forge_alias(&self) -> &ForgeAlias { + &self.forge_alias + } pub const fn repo_alias(&self) -> &RepoAlias { &self.repo_alias } diff --git a/crates/server/src/actors/server.rs b/crates/server/src/actors/server.rs index 9809ab0..68df2b9 100644 --- a/crates/server/src/actors/server.rs +++ b/crates/server/src/actors/server.rs @@ -5,7 +5,7 @@ use actix::prelude::*; use config::server::{ServerConfig, ServerStorage, Webhook}; use git_next_config::{ - self as config, ForgeConfig, ForgeName, GitDir, RepoAlias, ServerRepoConfig, + self as config, ForgeAlias, ForgeConfig, GitDir, RepoAlias, ServerRepoConfig, }; use git_next_git::{Generation, RepoDetails, Repository}; use git_next_repo_actor::{CloneRepo, RepoActor}; @@ -99,11 +99,13 @@ impl Handler for Server { let webhook = server_config.webhook(); // Forge Actors - for (forge_name, forge_config) in server_config.forges() { - self.create_forge_repos(forge_config, forge_name.clone(), server_storage, webhook) + for (forge_alias, forge_config) in server_config.forges() { + self.create_forge_repos(forge_config, forge_alias.clone(), server_storage, webhook) .into_iter() .map(|a| self.start_actor(a)) - .map(|(alias, addr)| AddWebhookRecipient(alias, addr.recipient())) + .map(|(repo_alias, addr)| { + AddWebhookRecipient::new(forge_alias.clone(), repo_alias, addr.recipient()) + }) .for_each(|msg| webhook_router.do_send(msg)); } @@ -146,10 +148,10 @@ impl Server { fn create_forge_repos( &self, forge_config: &ForgeConfig, - forge_name: ForgeName, + forge_name: ForgeAlias, server_storage: &ServerStorage, webhook: &Webhook, - ) -> Vec<(ForgeName, RepoAlias, RepoActor)> { + ) -> Vec<(ForgeAlias, RepoAlias, RepoActor)> { let span = tracing::info_span!("create_forge_repos", name = %forge_name, config = %forge_config); @@ -170,11 +172,11 @@ impl Server { fn create_actor( &self, - forge_name: ForgeName, + forge_name: ForgeAlias, forge_config: ForgeConfig, server_storage: &ServerStorage, webhook: &Webhook, - ) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeName, RepoAlias, RepoActor) { + ) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeAlias, RepoAlias, RepoActor) { let server_storage = server_storage.clone(); let webhook = webhook.clone(); let net = self.net.clone(); @@ -219,7 +221,7 @@ impl Server { fn start_actor( &self, - actor: (ForgeName, RepoAlias, RepoActor), + actor: (ForgeAlias, RepoAlias, RepoActor), ) -> (RepoAlias, Addr) { let (forge_name, repo_alias, actor) = actor; let span = tracing::info_span!("start_actor", forge = %forge_name, repo = %repo_alias); diff --git a/crates/server/src/actors/webhook/router.rs b/crates/server/src/actors/webhook/router.rs index 84efbb6..7205788 100644 --- a/crates/server/src/actors/webhook/router.rs +++ b/crates/server/src/actors/webhook/router.rs @@ -2,20 +2,21 @@ use std::collections::HashMap; use actix::prelude::*; -use git_next_config::RepoAlias; +use derive_more::Constructor; +use git_next_config::{ForgeAlias, RepoAlias}; use git_next_repo_actor::webhook::WebhookMessage; use tracing::{debug, info}; pub struct WebhookRouter { span: tracing::Span, - repos: HashMap>, + recipients: HashMap>>, } impl WebhookRouter { pub fn new() -> Self { let span = tracing::info_span!("WebhookRouter"); Self { span, - repos: Default::default(), + recipients: Default::default(), } } } @@ -28,24 +29,39 @@ impl Handler for WebhookRouter { fn handle(&mut self, msg: WebhookMessage, _ctx: &mut Self::Context) -> Self::Result { let _gaurd = self.span.enter(); + let forge_alias = msg.forge_alias(); let repo_alias = msg.repo_alias(); - debug!(repo = %repo_alias, "Router..."); - if let Some(recipient) = self.repos.get(repo_alias) { - info!(repo = %repo_alias, "Sending to Recipient"); - recipient.do_send(msg); - } + debug!(forge = %forge_alias, repo = %repo_alias, "Router..."); + let Some(forge_repos) = self.recipients.get(forge_alias) else { + return; + }; + let Some(recipient) = forge_repos.get(repo_alias) else { + return; + }; + info!(repo = %repo_alias, "Sending to Recipient"); + recipient.do_send(msg); } } -#[derive(Message)] +#[derive(Message, Constructor)] #[rtype(result = "()")] -pub struct AddWebhookRecipient(pub RepoAlias, pub Recipient); +pub struct AddWebhookRecipient { + pub forge_alias: ForgeAlias, + pub repo_alias: RepoAlias, + pub recipient: Recipient, +} impl Handler for WebhookRouter { type Result = (); fn handle(&mut self, msg: AddWebhookRecipient, _ctx: &mut Self::Context) -> Self::Result { let _gaurd = self.span.enter(); - info!(repo = %msg.0, "Register Recipient"); - self.repos.insert(msg.0, msg.1); + info!(forge = %msg.forge_alias, repo = %msg.repo_alias, "Register Recipient"); + if !self.recipients.contains_key(&msg.forge_alias) { + self.recipients + .insert(msg.forge_alias.clone(), HashMap::new()); + } + self.recipients + .get_mut(&msg.forge_alias) + .map(|repos| repos.insert(msg.repo_alias, msg.recipient)); } } diff --git a/crates/server/src/actors/webhook/server.rs b/crates/server/src/actors/webhook/server.rs index 927581b..57f3117 100644 --- a/crates/server/src/actors/webhook/server.rs +++ b/crates/server/src/actors/webhook/server.rs @@ -3,7 +3,7 @@ use std::net::SocketAddr; use actix::prelude::*; -use git_next_config::RepoAlias; +use git_next_config::{ForgeAlias, RepoAlias}; use git_next_repo_actor::webhook::{self, WebhookAuth, WebhookMessage}; use tracing::{info, warn}; use warp::reject::Rejection; @@ -15,17 +15,19 @@ pub async fn start(socket_addr: SocketAddr, address: actix::prelude::Recipient, - path: String, + forge_alias: String, + repo_alias: String, // query: String, headers: warp::http::HeaderMap, body: bytes::Bytes| async move { info!("POST received"); - let repo_alias = RepoAlias::new(path); + let forge_alias = ForgeAlias::new(forge_alias); + let repo_alias = RepoAlias::new(repo_alias); let bytes = body.to_vec(); let body = webhook::Body::new(String::from_utf8_lossy(&bytes).to_string()); headers.get("Authorization").map_or_else( @@ -34,10 +36,22 @@ pub async fn start(socket_addr: SocketAddr, address: actix::prelude::Recipient { - let message = WebhookMessage::new(repo_alias, authorisation, body); + let message = WebhookMessage::new( + forge_alias, + repo_alias, + authorisation, + body, + ); recipient .try_send(message) .map(|_| {