Adding repo whitelist.
This commit is contained in:
parent
cd56bb2fe1
commit
613026b326
1
Makefile
1
Makefile
@ -33,3 +33,4 @@ format: ## Auto-format source files.
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
> $(MAKE) -C docker/webhook_bridge_development clean
|
> $(MAKE) -C docker/webhook_bridge_development clean
|
||||||
|
> rm -rf target
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use kube::Client;
|
use kube::Client;
|
||||||
|
|
||||||
use crate::gitea_client::GiteaClient;
|
use crate::gitea_client::GiteaClient;
|
||||||
@ -6,4 +9,5 @@ use crate::gitea_client::GiteaClient;
|
|||||||
pub(crate) struct AppState {
|
pub(crate) struct AppState {
|
||||||
pub(crate) kubernetes_client: Client,
|
pub(crate) kubernetes_client: Client,
|
||||||
pub(crate) gitea: GiteaClient,
|
pub(crate) gitea: GiteaClient,
|
||||||
|
pub(crate) allowed_repos: Arc<HashSet<String>>,
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ pub(crate) struct HookPush {
|
|||||||
commits: Vec<HookCommit>,
|
commits: Vec<HookCommit>,
|
||||||
total_commits: u64,
|
total_commits: u64,
|
||||||
head_commit: HookCommit,
|
head_commit: HookCommit,
|
||||||
repository: HookRepository,
|
pub(crate) repository: HookRepository,
|
||||||
pusher: HookUser,
|
pusher: HookUser,
|
||||||
sender: HookUser,
|
sender: HookUser,
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ pub(crate) struct HookRepository {
|
|||||||
id: u64,
|
id: u64,
|
||||||
owner: HookUser,
|
owner: HookUser,
|
||||||
name: String,
|
name: String,
|
||||||
full_name: String,
|
pub(crate) full_name: String,
|
||||||
description: String,
|
description: String,
|
||||||
empty: bool,
|
empty: bool,
|
||||||
private: bool,
|
private: bool,
|
||||||
|
27
src/lib.rs
27
src/lib.rs
@ -1,4 +1,6 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
@ -35,7 +37,8 @@ pub async fn init_tracing() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(
|
.with(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
||||||
"webhook_bridge=info,tower_http=debug,axum::rejection=trace".into()
|
"webhookbridge=info,webhook_bridge=info,local_trigger=info,tower_http=debug,axum::rejection=trace"
|
||||||
|
.into()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.with(tracing_subscriber::fmt::layer())
|
.with(tracing_subscriber::fmt::layer())
|
||||||
@ -52,6 +55,15 @@ pub async fn launch_server() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
||||||
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
||||||
|
|
||||||
|
let allowed_repos = std::env::var("WEBHOOK_BRIDGE_REPO_WHITELIST")?;
|
||||||
|
let allowed_repos: HashSet<_> = allowed_repos
|
||||||
|
.split(",")
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(str::to_owned)
|
||||||
|
.collect();
|
||||||
|
tracing::debug!("Using repo whitelist: {:?}", allowed_repos);
|
||||||
|
|
||||||
|
let allowed_repos = HashSet::new();
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/hook", post(hook))
|
.route("/hook", post(hook))
|
||||||
.layer(middleware::from_fn(verify_signature))
|
.layer(middleware::from_fn(verify_signature))
|
||||||
@ -64,6 +76,7 @@ pub async fn launch_server() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.with_state(AppState {
|
.with_state(AppState {
|
||||||
kubernetes_client,
|
kubernetes_client,
|
||||||
gitea,
|
gitea,
|
||||||
|
allowed_repos: Arc::new(allowed_repos),
|
||||||
});
|
});
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:9988").await?;
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:9988").await?;
|
||||||
@ -83,9 +96,19 @@ pub async fn local_trigger(payload: &str) -> Result<(), Box<dyn std::error::Erro
|
|||||||
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
||||||
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
||||||
|
|
||||||
|
let allowed_repos = std::env::var("WEBHOOK_BRIDGE_REPO_WHITELIST")
|
||||||
|
.ok()
|
||||||
|
.unwrap_or_else(String::new);
|
||||||
|
let allowed_repos: HashSet<_> = allowed_repos
|
||||||
|
.split(",")
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(str::to_owned)
|
||||||
|
.collect();
|
||||||
|
tracing::debug!("Using repo whitelist: {:?}", allowed_repos);
|
||||||
|
|
||||||
let webhook_payload: HookPush = serde_json::from_str(payload)?;
|
let webhook_payload: HookPush = serde_json::from_str(payload)?;
|
||||||
|
|
||||||
handle_push(gitea, kubernetes_client, webhook_payload).await?;
|
handle_push(gitea, kubernetes_client, &allowed_repos, webhook_payload).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use axum::async_trait;
|
use axum::async_trait;
|
||||||
@ -40,7 +42,12 @@ pub(crate) async fn hook(
|
|||||||
debug!("REQ: {:?}", payload);
|
debug!("REQ: {:?}", payload);
|
||||||
match payload {
|
match payload {
|
||||||
HookRequest::Push(webhook_payload) => {
|
HookRequest::Push(webhook_payload) => {
|
||||||
handle_push(state.gitea, state.kubernetes_client, webhook_payload)
|
handle_push(
|
||||||
|
state.gitea,
|
||||||
|
state.kubernetes_client,
|
||||||
|
state.allowed_repos.borrow(),
|
||||||
|
webhook_payload,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to handle push event.");
|
.expect("Failed to handle push event.");
|
||||||
(
|
(
|
||||||
@ -167,11 +174,19 @@ fn hex_to_bytes(s: &str) -> Option<Vec<u8>> {
|
|||||||
pub(crate) async fn handle_push(
|
pub(crate) async fn handle_push(
|
||||||
gitea: GiteaClient,
|
gitea: GiteaClient,
|
||||||
kubernetes_client: kube::Client,
|
kubernetes_client: kube::Client,
|
||||||
|
allowed_repos: &HashSet<String>,
|
||||||
webhook_payload: HookPush,
|
webhook_payload: HookPush,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let repo_owner = webhook_payload.get_repo_owner()?;
|
let repo_owner = webhook_payload.get_repo_owner()?;
|
||||||
let repo_name = webhook_payload.get_repo_name()?;
|
let repo_name = webhook_payload.get_repo_name()?;
|
||||||
let pull_base_sha = webhook_payload.get_pull_base_sha()?;
|
let pull_base_sha = webhook_payload.get_pull_base_sha()?;
|
||||||
|
if !allowed_repos.contains(&webhook_payload.repository.full_name) {
|
||||||
|
tracing::info!(
|
||||||
|
"{} is not an allowed repository.",
|
||||||
|
webhook_payload.repository.full_name
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
let repo_tree = gitea.get_tree(repo_owner, repo_name, pull_base_sha).await?;
|
let repo_tree = gitea.get_tree(repo_owner, repo_name, pull_base_sha).await?;
|
||||||
let remote_config = discover_webhook_bridge_config(&gitea, &repo_tree).await?;
|
let remote_config = discover_webhook_bridge_config(&gitea, &repo_tree).await?;
|
||||||
let pipelines = discover_matching_push_triggers(
|
let pipelines = discover_matching_push_triggers(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user