mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
make billing an optional dependency for local dev
This commit is contained in:
1 parent
ba99be7081
commit
d372ac3a41
11 files changed
+184
-121
No files matched your search
Generated
-1
@@ -5994,7 +5994,6 @@ dependencies = [
|
||||
"actix-web",
|
||||
"actix_helpers",
|
||||
"anyhow",
|
||||
"async-stripe",
|
||||
"async-trait",
|
||||
"base64 0.21.5",
|
||||
"bcrypt",
|
||||
|
||||
@@ -1,60 +1,49 @@
|
||||
//! These routes are recommended, but do not have to be used by consumers of the billing system.
|
||||
|
||||
use actix_web::{App, HttpResponse, web};
|
||||
use actix_web::body::MessageBody;
|
||||
use actix_web::dev::{ServiceFactory, ServiceRequest, ServiceResponse};
|
||||
use actix_web::error::Error;
|
||||
|
||||
|
||||
use crate::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_json_handler::stripe_create_checkout_session_json_handler;
|
||||
use crate::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_redirect_handler::stripe_create_checkout_session_redirect_handler;
|
||||
use crate::stripe::http_endpoints::customer_portal::stripe_create_customer_portal_session_json_handler::stripe_create_customer_portal_session_json_handler;
|
||||
use crate::stripe::http_endpoints::customer_portal::stripe_create_customer_portal_session_redirect_handler::stripe_create_customer_portal_session_redirect_handler;
|
||||
use crate::stripe::http_endpoints::webhook::stripe_webhook_handler::stripe_webhook_handler;
|
||||
use actix_web::body::MessageBody;
|
||||
use actix_web::dev::{ServiceFactory, ServiceRequest, ServiceResponse};
|
||||
use actix_web::error::Error;
|
||||
use log::warn;
|
||||
|
||||
use crate::users::http_endpoints::list_active_user_subscriptions_handler::list_active_user_subscriptions_handler;
|
||||
|
||||
pub fn add_suggested_stripe_billing_routes<T, B> (app: App<T>) -> App<T>
|
||||
where
|
||||
B: MessageBody,
|
||||
T: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
pub fn add_suggested_stripe_billing_routes<T, B>(app: App<T>) -> App<T>
|
||||
where
|
||||
B: MessageBody,
|
||||
T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>,
|
||||
{
|
||||
app.service(web::scope("/v1")
|
||||
.service(web::scope("/billing")
|
||||
.service(web::resource("/active_subscriptions")
|
||||
.route(web::get().to(list_active_user_subscriptions_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
.service(web::scope("/stripe")
|
||||
.service(web::resource("/webhook")
|
||||
.route(web::post().to(stripe_webhook_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::scope("/checkout")
|
||||
.service(web::resource("/create_redirect")
|
||||
.route(web::post().to(stripe_create_checkout_session_json_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/redirect")
|
||||
.route(web::get().to(stripe_create_checkout_session_redirect_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
.service(web::scope("/portal")
|
||||
.service(web::resource("/create_redirect")
|
||||
.route(web::post().to(stripe_create_customer_portal_session_json_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/redirect")
|
||||
.route(web::get().to(stripe_create_customer_portal_session_redirect_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
)
|
||||
warn!("Adding suggested Stripe billing routes to app.");
|
||||
app.service(
|
||||
web::scope("/v1")
|
||||
.service(web::scope("/billing")
|
||||
.service(web::resource("/active_subscriptions")
|
||||
.route(web::get().to(list_active_user_subscriptions_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))))
|
||||
.service(web::scope("/stripe")
|
||||
.service(web::resource("/webhook")
|
||||
.route(web::post().to(stripe_webhook_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok())))
|
||||
.service(web::scope("/checkout")
|
||||
.service(web::resource("/create_redirect")
|
||||
.route(web::post().to(stripe_create_checkout_session_json_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok())))
|
||||
.service(web::resource("/redirect")
|
||||
.route(web::get().to(stripe_create_checkout_session_redirect_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))))
|
||||
.service(web::scope("/portal")
|
||||
.service(web::resource("/create_redirect")
|
||||
.route(web::post().to(stripe_create_customer_portal_session_json_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok())))
|
||||
.service(web::resource("/redirect")
|
||||
.route(web::get().to(stripe_create_customer_portal_session_redirect_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))))),
|
||||
)
|
||||
}
|
||||
@@ -51,7 +51,7 @@ url_config = { path = "../../../lib/url_config" }
|
||||
user_input_common = { path = "../../../lib/user_input_common" }
|
||||
|
||||
# Internal Components
|
||||
billing_component = { path = "../../plugins/billing" }
|
||||
billing_component = { path = "../../plugins/billing", optional = true }
|
||||
users_component = { path = "../../plugins/users" }
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
@@ -139,7 +139,7 @@ jwt = "0.13.0"
|
||||
hyper = { version = "0.14.24" }
|
||||
|
||||
# Money
|
||||
async-stripe = { version = "0.25.2", default-features = false, features = ["runtime-tokio-hyper-rustls-webpki", "connect", "billing", "checkout", "webhook-events"] }
|
||||
#async-stripe = { version = "0.25.2", default-features = false, features = ["runtime-tokio-hyper-rustls-webpki", "connect", "billing", "checkout", "webhook-events"] }
|
||||
|
||||
# Crypto
|
||||
bcrypt = "0.8" # password hashes
|
||||
@@ -172,3 +172,9 @@ diesel = { version = "2.1.3", features = ["mysql"] }
|
||||
|
||||
[dev-dependencies]
|
||||
speculoos = "0.9.0" # Fluent assertions
|
||||
|
||||
|
||||
[features]
|
||||
default = ["billing", "dep:billing_component"]
|
||||
billing = ["dep:billing_component"]
|
||||
all_except_billing = []
|
||||
+4
@@ -1,3 +1,5 @@
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::stripe::traits::internal_product_to_stripe_lookup::{InternalProductToStripeLookup, StripeProduct, StripeProductLookupError};
|
||||
use reusable_types::server_environment::ServerEnvironment;
|
||||
|
||||
@@ -7,6 +9,8 @@ use crate::configs::plans::plan_list::{DEVELOPMENT_PREMIUM_PLANS_BY_SLUG, PRODUC
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct InternalProductToStripeLookupImpl;
|
||||
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
impl InternalProductToStripeLookup for InternalProductToStripeLookupImpl {
|
||||
fn lookup_stripe_product_from_internal_product_key(&self, server_environment: ServerEnvironment, internal_product_key: &str) -> Result<Option<StripeProduct>, StripeProductLookupError> {
|
||||
let plans_by_slug = match server_environment {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use actix_web::HttpRequest;
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::stripe::traits::internal_session_cache_purge::InternalSessionCachePurge;
|
||||
use redis_caching::redis_ttl_cache::RedisTtlCache;
|
||||
use redis_common::redis_cache_keys::RedisCacheKeys;
|
||||
@@ -19,6 +20,7 @@ impl InternalSessionCachePurgeImpl {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
impl InternalSessionCachePurge for InternalSessionCachePurgeImpl {
|
||||
fn best_effort_purge_session_cache(&self, http_request: &HttpRequest) {
|
||||
// TODO: Clear Redis cache of sessions
|
||||
|
||||
+3
@@ -1,3 +1,5 @@
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::stripe::traits::internal_subscription_product_lookup::{InternalProductLookupError, InternalSubscriptionProduct, InternalSubscriptionProductLookup};
|
||||
|
||||
use crate::configs::plans::plan_list::{PLANS_BY_STRIPE_PRICE_ID, PLANS_BY_STRIPE_PRODUCT_ID};
|
||||
@@ -8,6 +10,7 @@ const SUBSCRIPTION_CATEGORY : &str = "fakeyou";
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct StripeInternalSubscriptionProductLookupImpl;
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
impl InternalSubscriptionProductLookup for StripeInternalSubscriptionProductLookupImpl {
|
||||
fn lookup_internal_product_from_stripe_product_id(&self, stripe_product_id: &str) -> Result<Option<InternalSubscriptionProduct>, InternalProductLookupError> {
|
||||
Ok(PLANS_BY_STRIPE_PRODUCT_ID.get(stripe_product_id)
|
||||
|
||||
@@ -3,6 +3,7 @@ use async_trait::async_trait;
|
||||
use chrono::Utc;
|
||||
use log::warn;
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::stripe::traits::internal_user_lookup::{InternalUserLookup, InternalUserLookupError, SubscriptionKey, UserMetadata};
|
||||
use users_component::utils::session_checker::SessionChecker;
|
||||
|
||||
@@ -25,6 +26,7 @@ impl StripeInternalUserLookupImpl {
|
||||
}
|
||||
|
||||
// NB: Marking async_trait as not needing Sync/Send. Hopefully this doesn't blow up on us.
|
||||
#[cfg(feature = "billing")]
|
||||
#[async_trait(?Send)]
|
||||
impl InternalUserLookup for StripeInternalUserLookupImpl {
|
||||
async fn lookup_user_from_http_request(&self, http_request: &HttpRequest) -> Result<Option<UserMetadata>, InternalUserLookupError> {
|
||||
|
||||
@@ -46,11 +46,6 @@ use actix_helpers::middleware::disabled_endpoint_filter::disabled_endpoint_filte
|
||||
use actix_helpers::middleware::disabled_endpoint_filter::disabled_endpoints::disabled_endpoints::DisabledEndpoints;
|
||||
use actix_helpers::middleware::disabled_endpoint_filter::disabled_endpoints::exact_match_disabled_endpoints::ExactMatchDisabledEndpoints;
|
||||
use actix_helpers::middleware::disabled_endpoint_filter::disabled_endpoints::prefix_disabled_endpoints::PrefixDisabledEndpoints;
|
||||
use billing_component::stripe::stripe_config::{FullUrlOrPath, StripeCheckoutConfigs, StripeConfig, StripeCustomerPortalConfigs, StripeSecrets};
|
||||
use billing_component::stripe::traits::internal_product_to_stripe_lookup::InternalProductToStripeLookup;
|
||||
use billing_component::stripe::traits::internal_session_cache_purge::InternalSessionCachePurge;
|
||||
use billing_component::stripe::traits::internal_subscription_product_lookup::InternalSubscriptionProductLookup;
|
||||
use billing_component::stripe::traits::internal_user_lookup::InternalUserLookup;
|
||||
use bootstrap::bootstrap::{bootstrap, BootstrapArgs};
|
||||
use cloud_storage::bucket_client::BucketClient;
|
||||
use config::common_env::CommonEnv;
|
||||
@@ -71,10 +66,19 @@ use users_component::cookies::anonymous_visitor_tracking::avt_cookie_manager::Av
|
||||
use users_component::cookies::session::session_cookie_manager::SessionCookieManager;
|
||||
use users_component::utils::session_checker::SessionChecker;
|
||||
|
||||
use crate::billing::internal_product_to_stripe_lookup_impl::InternalProductToStripeLookupImpl;
|
||||
use crate::billing::internal_session_cache_purge_impl::InternalSessionCachePurgeImpl;
|
||||
use crate::billing::stripe_internal_subscription_product_lookup_impl::StripeInternalSubscriptionProductLookupImpl;
|
||||
use crate::billing::stripe_internal_user_lookup_impl::StripeInternalUserLookupImpl;
|
||||
#[cfg(feature = "billing")]
|
||||
use
|
||||
{
|
||||
crate::billing::internal_product_to_stripe_lookup_impl::InternalProductToStripeLookupImpl,
|
||||
crate::billing::internal_session_cache_purge_impl::InternalSessionCachePurgeImpl,
|
||||
crate::billing::stripe_internal_subscription_product_lookup_impl::StripeInternalSubscriptionProductLookupImpl,
|
||||
crate::billing::stripe_internal_user_lookup_impl::StripeInternalUserLookupImpl,
|
||||
billing_component::stripe::stripe_config::{FullUrlOrPath, StripeCheckoutConfigs, StripeConfig, StripeCustomerPortalConfigs, StripeSecrets},
|
||||
billing_component::stripe::traits::internal_product_to_stripe_lookup::InternalProductToStripeLookup,
|
||||
billing_component::stripe::traits::internal_session_cache_purge::InternalSessionCachePurge,
|
||||
billing_component::stripe::traits::internal_subscription_product_lookup::InternalSubscriptionProductLookup,
|
||||
billing_component::stripe::traits::internal_user_lookup::InternalUserLookup,
|
||||
};
|
||||
use crate::configs::static_api_tokens::{StaticApiTokenConfig, StaticApiTokens, StaticApiTokenSet};
|
||||
use crate::http_server::middleware::pushback_filter_middleware::PushbackFilter;
|
||||
use crate::http_server::web_utils::redis_rate_limiter::RedisRateLimiter;
|
||||
@@ -382,6 +386,7 @@ async fn main() -> AnyhowResult<()> {
|
||||
});
|
||||
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
let stripe_configs = StripeConfig {
|
||||
checkout: StripeCheckoutConfigs {
|
||||
success_url: FullUrlOrPath::Path(easyenv::get_env_string_required("STRIPE_CHECKOUT_SUCCESS_URL_PATH")?),
|
||||
@@ -398,6 +403,9 @@ async fn main() -> AnyhowResult<()> {
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "billing"))]
|
||||
let stripe_configs = ();
|
||||
|
||||
let server_environment = ServerEnvironment::from_str(&easyenv::get_env_string_required("SERVER_ENVIRONMENT")?)
|
||||
.ok_or(anyhow!("invalid server environment"))?;
|
||||
|
||||
@@ -424,10 +432,6 @@ async fn main() -> AnyhowResult<()> {
|
||||
|
||||
let third_party_url_redirector = ThirdPartyUrlRedirector::new(server_environment);
|
||||
|
||||
let stripe_client = {
|
||||
let api_secret = stripe_configs.secrets.secret_key.clone();
|
||||
stripe::Client::new(api_secret)
|
||||
};
|
||||
|
||||
// NB: Docker creates this file within container builds.
|
||||
let build_sha = std::fs::read_to_string("/GIT_SHA")
|
||||
@@ -455,7 +459,6 @@ async fn main() -> AnyhowResult<()> {
|
||||
},
|
||||
stripe: StripeSettings {
|
||||
config: stripe_configs,
|
||||
client: stripe_client,
|
||||
},
|
||||
hostname: server_hostname,
|
||||
server_environment,
|
||||
@@ -636,62 +639,105 @@ pub async fn serve(server_state: ServerState) -> AnyhowResult<()>
|
||||
//let log_format = "[%{HOSTNAME}e] %a \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %T";
|
||||
let log_format = "[%{HOSTNAME}e] IP=[%{X-Forwarded-For}i] \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %T";
|
||||
|
||||
HttpServer::new(move || {
|
||||
// NB: Safe to clone due to internal arc
|
||||
let ip_ban_list = server_state_arc.ip_ban_list.clone();
|
||||
let cidr_ban_set= server_state_arc.cidr_ban_set.clone();
|
||||
#[cfg(feature = "billing")]
|
||||
{
|
||||
let server = HttpServer::new(move || {
|
||||
// NB: Safe to clone due to internal arc
|
||||
let ip_ban_list = server_state_arc.ip_ban_list.clone();
|
||||
let cidr_ban_set= server_state_arc.cidr_ban_set.clone();
|
||||
|
||||
// NB: Dynamic dispatch needs to be wrapped with Arc.
|
||||
let product_lookup : Arc<dyn InternalSubscriptionProductLookup> = Arc::new(StripeInternalSubscriptionProductLookupImpl {});
|
||||
let stripe_lookup : Arc<dyn InternalProductToStripeLookup> = Arc::new(InternalProductToStripeLookupImpl{});
|
||||
let user_lookup : Arc<dyn InternalUserLookup> = Arc::new(StripeInternalUserLookupImpl::new(
|
||||
server_state_arc.session_checker.clone(),
|
||||
server_state_arc.mysql_pool.clone(),
|
||||
));
|
||||
let session_cache_purge : Arc<dyn InternalSessionCachePurge> = Arc::new(InternalSessionCachePurgeImpl::new(
|
||||
server_state_arc.session_checker.clone(),
|
||||
server_state_arc.redis_ttl_cache.clone(),
|
||||
));
|
||||
// NB: Dynamic dispatch needs to be wrapped with Arc.
|
||||
let product_lookup : Arc<dyn InternalSubscriptionProductLookup> = Arc::new(StripeInternalSubscriptionProductLookupImpl {});
|
||||
let stripe_lookup : Arc<dyn InternalProductToStripeLookup> = Arc::new(InternalProductToStripeLookupImpl{});
|
||||
let user_lookup : Arc<dyn InternalUserLookup> = Arc::new(StripeInternalUserLookupImpl::new(
|
||||
server_state_arc.session_checker.clone(),
|
||||
server_state_arc.mysql_pool.clone(),
|
||||
));
|
||||
let session_cache_purge : Arc<dyn InternalSessionCachePurge> = Arc::new(InternalSessionCachePurgeImpl::new(
|
||||
server_state_arc.session_checker.clone(),
|
||||
server_state_arc.redis_ttl_cache.clone(),
|
||||
));
|
||||
|
||||
// NB: app_data being clone()'d below should all be safe (dependencies included)
|
||||
let app = App::new()
|
||||
.app_data(web::Data::new(server_state_arc.firehose_publisher.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.mysql_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_ttl_cache.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_checker.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.avt_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.stripe.clone().config.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.stripe.clone().client.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.third_party_url_redirector.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.email_sender.clone()))
|
||||
.app_data(web::Data::new(old_server_environment))
|
||||
.app_data(web::Data::new(new_server_environment))
|
||||
.app_data(web::Data::from(product_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(stripe_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(user_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(session_cache_purge)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(server_state_arc.clone())
|
||||
.wrap(build_cors_config(old_server_environment))
|
||||
.wrap(DefaultHeaders::new()
|
||||
.header("X-Backend-Hostname", &hostname)
|
||||
.header("X-Build-Sha", server_state_arc.server_info.build_sha.clone()))
|
||||
.wrap(PushbackFilter::new(&server_state_arc.flags.clone()))
|
||||
.wrap(DisabledEndpointFilter::new(disabled_endpoints.clone()))
|
||||
.wrap(BannedIpFilter::new(ip_ban_list))
|
||||
.wrap(BannedCidrFilter::new(cidr_ban_set))
|
||||
.wrap(Logger::new(&log_format)
|
||||
.exclude("/liveness")
|
||||
.exclude("/readiness"))
|
||||
.wrap(middleware::Compress::default());
|
||||
// NB: app_data being clone()'d below should all be safe (dependencies included)
|
||||
let app = App::new()
|
||||
.app_data(web::Data::new(server_state_arc.firehose_publisher.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.mysql_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_ttl_cache.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_checker.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.avt_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.stripe.clone().config.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.third_party_url_redirector.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.email_sender.clone()))
|
||||
.app_data(web::Data::new(old_server_environment))
|
||||
.app_data(web::Data::new(new_server_environment))
|
||||
.app_data(web::Data::from(product_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(stripe_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(user_lookup)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(web::Data::from(session_cache_purge)) // NB: Data::from(Arc<T>) for dynamic dispatch
|
||||
.app_data(server_state_arc.clone())
|
||||
.wrap(build_cors_config(old_server_environment))
|
||||
.wrap(DefaultHeaders::new()
|
||||
.header("X-Backend-Hostname", &hostname)
|
||||
.header("X-Build-Sha", server_state_arc.server_info.build_sha.clone()))
|
||||
.wrap(PushbackFilter::new(&server_state_arc.flags.clone()))
|
||||
.wrap(DisabledEndpointFilter::new(disabled_endpoints.clone()))
|
||||
.wrap(BannedIpFilter::new(ip_ban_list))
|
||||
.wrap(BannedCidrFilter::new(cidr_ban_set))
|
||||
.wrap(Logger::new(&log_format)
|
||||
.exclude("/liveness")
|
||||
.exclude("/readiness"))
|
||||
.wrap(middleware::Compress::default());
|
||||
|
||||
add_routes(app, old_server_environment)
|
||||
})
|
||||
.bind(bind_address)?
|
||||
.workers(num_workers)
|
||||
.run()
|
||||
.await?;
|
||||
crate::routes::add_routes(app, old_server_environment)
|
||||
});
|
||||
|
||||
server.bind(bind_address)?
|
||||
.workers(num_workers)
|
||||
.run()
|
||||
.await?;
|
||||
}
|
||||
#[cfg(not(feature = "billing"))] {
|
||||
let server = HttpServer::new(move || {
|
||||
// NB: Safe to clone due to internal arc
|
||||
let ip_ban_list = server_state_arc.ip_ban_list.clone();
|
||||
let cidr_ban_set= server_state_arc.cidr_ban_set.clone();
|
||||
|
||||
// NB: app_data being clone()'d below should all be safe (dependencies included)
|
||||
let app = App::new()
|
||||
.app_data(web::Data::new(server_state_arc.firehose_publisher.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.mysql_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_pool.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.redis_ttl_cache.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_checker.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.avt_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.session_cookie_manager.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.third_party_url_redirector.clone()))
|
||||
.app_data(web::Data::new(server_state_arc.email_sender.clone()))
|
||||
.app_data(web::Data::new(old_server_environment))
|
||||
.app_data(web::Data::new(new_server_environment))
|
||||
.app_data(server_state_arc.clone())
|
||||
.wrap(build_cors_config(old_server_environment))
|
||||
.wrap(DefaultHeaders::new()
|
||||
.header("X-Backend-Hostname", &hostname)
|
||||
.header("X-Build-Sha", server_state_arc.server_info.build_sha.clone()))
|
||||
.wrap(PushbackFilter::new(&server_state_arc.flags.clone()))
|
||||
.wrap(DisabledEndpointFilter::new(disabled_endpoints.clone()))
|
||||
.wrap(BannedIpFilter::new(ip_ban_list))
|
||||
.wrap(BannedCidrFilter::new(cidr_ban_set))
|
||||
.wrap(Logger::new(&log_format)
|
||||
.exclude("/liveness")
|
||||
.exclude("/readiness"))
|
||||
.wrap(middleware::Compress::default());
|
||||
|
||||
add_routes(app, old_server_environment)
|
||||
});
|
||||
server.bind(bind_address)?
|
||||
.workers(num_workers)
|
||||
.run()
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::error::Error;
|
||||
|
||||
use actix_helpers::route_builder::RouteBuilder;
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::default_routes::add_suggested_stripe_billing_routes;
|
||||
use reusable_types::server_environment::ServerEnvironment;
|
||||
use users_component::default_routes::add_suggested_api_v1_account_creation_and_session_routes;
|
||||
@@ -228,15 +229,20 @@ pub fn add_routes<T, B> (app: App<T>, server_environment: ServerEnvironment) ->
|
||||
|
||||
// ==================== Stats ====================
|
||||
|
||||
|
||||
let mut app = RouteBuilder::from_app(app)
|
||||
.add_get("/v1/stats/queues", get_unified_queue_stats_handler)
|
||||
.into_app();
|
||||
|
||||
// ==================== COMPONENTS ====================
|
||||
|
||||
app = add_suggested_api_v1_account_creation_and_session_routes(app); // /create_account, /session, /login, /logout
|
||||
app = add_suggested_stripe_billing_routes(app); // /stripe, billing, webhooks, etc.
|
||||
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
let mut app = add_suggested_stripe_billing_routes(app); // /stripe, billing, webhooks, etc.
|
||||
|
||||
#[cfg(not(feature = "billing"))]
|
||||
let mut app = app;
|
||||
|
||||
// ==================== SERVICE ====================
|
||||
app.service(
|
||||
web::resource("/_status")
|
||||
|
||||
@@ -4,6 +4,7 @@ use sqlx::MySqlPool;
|
||||
|
||||
use actix_helpers::middleware::banned_cidr_filter::banned_cidr_set::BannedCidrSet;
|
||||
use actix_helpers::middleware::banned_ip_filter::ip_ban_list::ip_ban_list::IpBanList;
|
||||
#[cfg(feature = "billing")]
|
||||
use billing_component::stripe::stripe_config::StripeConfig;
|
||||
use cloud_storage::bucket_client::BucketClient;
|
||||
use email_sender::smtp_email_sender::SmtpEmailSender;
|
||||
@@ -197,10 +198,16 @@ pub struct EphemeralInMemoryCaches {
|
||||
pub leaderboard: SingleItemTtlCache<LeaderboardInfo>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "billing")]
|
||||
#[derive(Clone)]
|
||||
pub struct StripeSettings {
|
||||
pub config: StripeConfig,
|
||||
pub client: stripe::Client,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "billing"))]
|
||||
#[derive(Clone)]
|
||||
pub struct StripeSettings {
|
||||
pub config: ()
|
||||
}
|
||||
|
||||
/// Flags set at service startup
|
||||
|
||||
Vendored
-1
@@ -22,7 +22,6 @@ chrono = "0.4.9"
|
||||
futures = "0.1.29"
|
||||
redis = "0.13.0"
|
||||
time = "0.1.42"
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
Reference in new issue
Block a user