From f8d6d75cc477755a20c270fa2a8a3dc02880fd8b Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 11 Apr 2024 22:51:59 -0400 Subject: [PATCH] cors for storytellerstudio.netlify --- .../src/configs/gottagofast.rs | 99 +++++++++++-------- crates/lib/actix_cors_configs/src/lib.rs | 1 + crates/lib/actix_cors_configs/src/util/mod.rs | 1 + .../src/util/netlify_branch_domain_matches.rs | 32 ++++++ 4 files changed, 90 insertions(+), 43 deletions(-) create mode 100644 crates/lib/actix_cors_configs/src/util/mod.rs create mode 100644 crates/lib/actix_cors_configs/src/util/netlify_branch_domain_matches.rs diff --git a/crates/lib/actix_cors_configs/src/configs/gottagofast.rs b/crates/lib/actix_cors_configs/src/configs/gottagofast.rs index 389ccdd40d..19ca1a07f9 100644 --- a/crates/lib/actix_cors_configs/src/configs/gottagofast.rs +++ b/crates/lib/actix_cors_configs/src/configs/gottagofast.rs @@ -1,33 +1,13 @@ use actix_cors::Cors; -use log::warn; -use url::{Host, Url}; +use crate::util::netlify_branch_domain_matches::netlify_branch_domain_matches; pub fn add_gotta_go_fast_test_branches(cors: Cors, _is_production: bool) -> Cors { cors.allowed_origin("http://localhost:5173") - .allowed_origin("https://pipeline-gottagofast.netlify.app") - .allowed_origin("https://test--pipeline-gottagofast.netlify.app") - // Allow Netlify domains within "gottagofast" project. .allowed_origin_fn(|origin, _req_head| { - let maybe_url = origin.to_str() - .map(|origin| Url::parse(origin)); - - let url = match maybe_url { - Ok(Ok(url)) => url, - _ => { - warn!("Invalid origin: {:?}", origin); - return false - }, - }; - - match url.host() { - Some(Host::Domain(domain)) => { - let is_netlify_domain = domain == "pipeline-gottagofast.netlify.app"; - let is_netlify_branch_deploy = domain.ends_with("--pipeline-gottagofast.netlify.app"); - - is_netlify_domain || is_netlify_branch_deploy - }, - _ => false, - } + netlify_branch_domain_matches(origin, "pipeline-gottagofast.netlify.app") + }) + .allowed_origin_fn(|origin, _req_head| { + netlify_branch_domain_matches(origin, "storytellerstudio.netlify.app") }) } @@ -39,27 +19,60 @@ mod tests { use crate::testing::assert_origin_invalid; use crate::testing::assert_origin_ok; - #[actix_rt::test] - async fn gotta_go_fast_main() { - let production_cors = build_cors_config(ServerEnvironment::Production); - assert_origin_ok(&production_cors, "https://pipeline-gottagofast.netlify.app").await; + mod gotta_go_fast { + use super::*; + + #[actix_rt::test] + async fn gotta_go_fast_main() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://pipeline-gottagofast.netlify.app").await; + } + + #[actix_rt::test] + async fn gotta_go_fast_branch_deploy() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://test--pipeline-gottagofast.netlify.app").await; + } + + #[actix_rt::test] + async fn gotta_go_fast_deploy_preview() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://deploy-preview-86--pipeline-gottagofast.netlify.app").await; + } + + #[actix_rt::test] + async fn invalid_netlify_preview_deploy() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_invalid(&production_cors, "https://deploy-preview-86--unrelated-project.netlify.app").await; + } } - #[actix_rt::test] - async fn gotta_go_fast_branch_deploy() { - let production_cors = build_cors_config(ServerEnvironment::Production); - assert_origin_ok(&production_cors, "https://test--pipeline-gottagofast.netlify.app").await; - } + mod studio { + use super::*; - #[actix_rt::test] - async fn gotta_go_fast_deploy_preview() { - let production_cors = build_cors_config(ServerEnvironment::Production); - assert_origin_ok(&production_cors, "https://deploy-preview-86--pipeline-gottagofast.netlify.app").await; - } + #[actix_rt::test] + async fn studio_main() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://storytellerstudio.netlify.app").await; + } - #[actix_rt::test] - async fn invalid_netlify_preview_deploy() { - let production_cors = build_cors_config(ServerEnvironment::Production); - assert_origin_invalid(&production_cors, "https://deploy-preview-86--unrelated-project.netlify.app").await; + #[actix_rt::test] + async fn studio_branch_deploy() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://foo--storytellerstudio.netlify.app").await; + } + + #[actix_rt::test] + async fn studio_deploy_preview() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_ok(&production_cors, "https://deploy-preview-123--storytellerstudio.netlify.app").await; + } + + #[actix_rt::test] + async fn invalid_netlify_preview_deploy() { + let production_cors = build_cors_config(ServerEnvironment::Production); + assert_origin_invalid(&production_cors, "https://fakestorytellerstudio.netlify.app").await; + assert_origin_invalid(&production_cors, "https://deploy-preview-86--fakestorytellerstudio.netlify.app").await; + } } } diff --git a/crates/lib/actix_cors_configs/src/lib.rs b/crates/lib/actix_cors_configs/src/lib.rs index 2a677a6515..f2d82f6b4d 100644 --- a/crates/lib/actix_cors_configs/src/lib.rs +++ b/crates/lib/actix_cors_configs/src/lib.rs @@ -23,6 +23,7 @@ pub mod cors; pub mod shared_array_buffer_cors; pub (crate) mod configs; +pub (crate) mod util; #[cfg(test)] pub (crate) mod testing; diff --git a/crates/lib/actix_cors_configs/src/util/mod.rs b/crates/lib/actix_cors_configs/src/util/mod.rs new file mode 100644 index 0000000000..6aa0aea01f --- /dev/null +++ b/crates/lib/actix_cors_configs/src/util/mod.rs @@ -0,0 +1 @@ +pub mod netlify_branch_domain_matches; diff --git a/crates/lib/actix_cors_configs/src/util/netlify_branch_domain_matches.rs b/crates/lib/actix_cors_configs/src/util/netlify_branch_domain_matches.rs new file mode 100644 index 0000000000..81d30ea6ab --- /dev/null +++ b/crates/lib/actix_cors_configs/src/util/netlify_branch_domain_matches.rs @@ -0,0 +1,32 @@ +use actix_http::header::HeaderValue; +use log::warn; +use url::{Host, Url}; + +// TODO(bt, 2024-04-11): This is inefficient for middleware +pub fn netlify_branch_domain_matches(origin: &HeaderValue, netlify_hostname: &str) -> bool { + let maybe_url = origin.to_str() + .map(|origin| Url::parse(origin)); + + let url = match maybe_url { + Ok(Ok(url)) => url, + _ => { + warn!("Invalid origin: {:?}", origin); + return false + }, + }; + + match url.host() { + Some(Host::Domain(domain)) => { + let is_netlify_domain = domain == netlify_hostname; + if is_netlify_domain { + return true; + } + + let branch_suffix = format!("--{}", netlify_hostname); + let is_netlify_branch_deploy = domain.ends_with(&branch_suffix); + + is_netlify_branch_deploy + }, + _ => false, + } +}