From 47a71ccde44663d2cc94343a9e857f2a17ef16ba Mon Sep 17 00:00:00 2001 From: HugoCasa Date: Wed, 6 Dec 2023 17:47:32 +0100 Subject: [PATCH] feat: limit pro plans (#2794) --- backend/windmill-api/src/lib.rs | 7 ++++- backend/windmill-api/src/saml.rs | 8 ++++++ backend/windmill-audit/src/lib.rs | 24 ++++++++++++----- backend/windmill-common/src/ee.rs | 15 +++++++++++ .../windmill-worker/src/python_executor.rs | 26 +++++++++++++------ backend/windmill-worker/src/worker.rs | 10 +++++-- .../lib/components/InstanceSettings.svelte | 2 +- .../(root)/(logged)/audit_logs/+page.svelte | 2 +- .../(root)/(logged)/workers/+page.svelte | 2 +- 9 files changed, 76 insertions(+), 20 deletions(-) diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index 5a80df0434..f0fc4221ba 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -36,6 +36,8 @@ use tower_http::{ trace::TraceLayer, }; use windmill_common::db::UserDB; +#[cfg(feature = "enterprise")] +use windmill_common::ee::{get_license_plan, LicensePlan}; use windmill_common::utils::rd_string; use windmill_common::worker::ALL_TAGS; use windmill_common::BASE_URL; @@ -159,7 +161,10 @@ pub async fn run_server( .allow_origin(Any); #[cfg(feature = "enterprise")] - let sp_extension: (ServiceProviderExt, SamlSsoLogin) = saml::build_sp_extension().await?; + let sp_extension: (ServiceProviderExt, SamlSsoLogin) = match get_license_plan().await { + LicensePlan::Enterprise => saml::build_sp_extension().await?, + LicensePlan::Pro => (ServiceProviderExt(None), SamlSsoLogin(None)), + }; #[cfg(not(feature = "enterprise"))] let sp_extension = (ServiceProviderExt(), SamlSsoLogin(None)); diff --git a/backend/windmill-api/src/saml.rs b/backend/windmill-api/src/saml.rs index 8bf41e82aa..c07cf1651c 100644 --- a/backend/windmill-api/src/saml.rs +++ b/backend/windmill-api/src/saml.rs @@ -40,6 +40,9 @@ pub struct ServiceProviderExt(pub Option); #[cfg(not(feature = "enterprise"))] pub struct ServiceProviderExt(); +#[cfg(feature = "enterprise")] +use windmill_common::ee::{get_license_plan, LicensePlan}; + pub struct SamlSsoLogin(pub Option); #[cfg(feature = "enterprise")] @@ -97,6 +100,11 @@ pub async fn acs( Extension(se): Extension>, Form(s): Form, ) -> Result { + if matches!(get_license_plan().await, LicensePlan::Pro) { + return Err(Error::BadRequest( + "SAML not available in the pro plan".to_string(), + )); + }; if let Some(sp_m) = &se.0 { let sp = sp_m.clone(); if let Some(encoded_resp) = s.SAMLResponse { diff --git a/backend/windmill-audit/src/lib.rs b/backend/windmill-audit/src/lib.rs index 71bfb12a7b..12b25f2fd9 100644 --- a/backend/windmill-audit/src/lib.rs +++ b/backend/windmill-audit/src/lib.rs @@ -15,6 +15,9 @@ use windmill_common::{ utils::Pagination, }; +#[cfg(feature = "enterprise")] +use windmill_common::ee::{get_license_plan, LicensePlan}; + use serde::{Deserialize, Serialize}; use sql_builder::SqlBuilder; use sqlx::{FromRow, Postgres, Transaction}; @@ -44,23 +47,32 @@ pub struct AuditLog { pub async fn audit_log<'c, E: sqlx::Executor<'c, Database = Postgres>>( db: E, username: &str, - _operation: &str, + mut _operation: &str, action_kind: ActionKind, w_id: &str, - _resource: Option<&str>, + mut _resource: Option<&str>, _parameters: Option>, ) -> Result<()> { #[cfg(feature = "enterprise")] - let p_json: serde_json::Value = serde_json::to_value(&_parameters).unwrap(); + let p_json = match get_license_plan().await { + LicensePlan::Enterprise => serde_json::to_value(&_parameters).unwrap(), + LicensePlan::Pro => serde_json::json!({"redacted": "-"}), + }; #[cfg(not(feature = "enterprise"))] let p_json: serde_json::Value = serde_json::json!({"redacted": "-"}); - #[cfg(not(feature = "enterprise"))] - let _resource: Option<&str> = Some("EE only"); + #[cfg(feature = "enterprise")] + if matches!(get_license_plan().await, LicensePlan::Pro) { + _resource = Some("EE only"); + _operation = "redacted"; + } #[cfg(not(feature = "enterprise"))] - let _operation: &str = "redacted"; + { + _resource = Some("EE only"); + _operation = "redacted"; + } tracing::info!( operation = _operation, diff --git a/backend/windmill-common/src/ee.rs b/backend/windmill-common/src/ee.rs index a58cf17e35..d70982d8bd 100644 --- a/backend/windmill-common/src/ee.rs +++ b/backend/windmill-common/src/ee.rs @@ -6,3 +6,18 @@ lazy_static::lazy_static! { pub static ref LICENSE_KEY_ID: Arc> = Arc::new(RwLock::new("".to_string())); pub static ref LICENSE_KEY: Arc> = Arc::new(RwLock::new("".to_string())); } + +pub enum LicensePlan { + Pro, + Enterprise, +} + +pub async fn get_license_plan() -> LicensePlan { + let id = LICENSE_KEY_ID.read().await.clone(); + + if id.ends_with("_pro") { + LicensePlan::Pro + } else { + LicensePlan::Enterprise + } +} diff --git a/backend/windmill-worker/src/python_executor.rs b/backend/windmill-worker/src/python_executor.rs index 1e7fd91730..b758c8d35a 100644 --- a/backend/windmill-worker/src/python_executor.rs +++ b/backend/windmill-worker/src/python_executor.rs @@ -10,6 +10,8 @@ use tokio::{ process::Command, }; use uuid::Uuid; +#[cfg(feature = "enterprise")] +use windmill_common::ee::{get_license_plan, LicensePlan}; use windmill_common::{ error::{self, Error}, jobs::QueuedJob, @@ -649,12 +651,16 @@ pub async fn handle_python_reqs( #[cfg(feature = "enterprise")] if let Some(ref bucket) = *S3_CACHE_BUCKET { - sqlx::query_scalar!("UPDATE queue SET last_ping = now() WHERE id = $1", job_id) - .execute(db) - .await?; - if pull_from_tar(bucket, venv_p.clone()).await.is_ok() { - req_paths.push(venv_p.clone()); - continue; + if matches!(get_license_plan().await, LicensePlan::Pro) { + tracing::warn!("S3 cache not available in the pro plan"); + } else { + sqlx::query_scalar!("UPDATE queue SET last_ping = now() WHERE id = $1", job_id) + .execute(db) + .await?; + if pull_from_tar(bucket, venv_p.clone()).await.is_ok() { + req_paths.push(venv_p.clone()); + continue; + } } } @@ -770,8 +776,12 @@ pub async fn handle_python_reqs( #[cfg(feature = "enterprise")] if let Some(ref bucket) = *S3_CACHE_BUCKET { - let venv_p = venv_p.clone(); - tokio::spawn(build_tar_and_push(bucket, venv_p)); + if matches!(get_license_plan().await, LicensePlan::Pro) { + tracing::warn!("S3 cache not available in the pro plan"); + } else { + let venv_p = venv_p.clone(); + tokio::spawn(build_tar_and_push(bucket, venv_p)); + } } req_paths.push(venv_p); } diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index 16ca0c47fa..8d478c266d 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -27,6 +27,8 @@ use std::{ }; use uuid::Uuid; +#[cfg(feature = "enterprise")] +use windmill_common::ee::{get_license_plan, LicensePlan}; use windmill_common::{ error::{self, to_anyhow, Error}, flows::{FlowModule, FlowModuleValue, FlowValue}, @@ -855,7 +857,9 @@ pub async fn run_worker *GLOBAL_CACHE_INTERVAL + if matches!(get_license_plan().await, LicensePlan::Pro) { + tracing::warn!("S3 cache not available in the pro plan"); + } else if last_sync.elapsed().as_secs() > *GLOBAL_CACHE_INTERVAL && (copy_cache_from_bucket_handle.is_none() || copy_cache_from_bucket_handle .as_ref() diff --git a/frontend/src/lib/components/InstanceSettings.svelte b/frontend/src/lib/components/InstanceSettings.svelte index 2c66b88834..0c6a24b6a3 100644 --- a/frontend/src/lib/components/InstanceSettings.svelte +++ b/frontend/src/lib/components/InstanceSettings.svelte @@ -197,7 +197,7 @@ {#if category == 'SSO/OAuth'}

SSO

- {#if !$enterpriseLicense} + {#if !$enterpriseLicense || $enterpriseLicense.endsWith('_pro')} Without EE, the number of SSO users is limited to 10. SCIM/SAML is available on EE diff --git a/frontend/src/routes/(root)/(logged)/audit_logs/+page.svelte b/frontend/src/routes/(root)/(logged)/audit_logs/+page.svelte index 062832cfdf..22f301af5b 100644 --- a/frontend/src/routes/(root)/(logged)/audit_logs/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/audit_logs/+page.svelte @@ -71,7 +71,7 @@
- {#if !$enterpriseLicense} + {#if !$enterpriseLicense || $enterpriseLicense.endsWith('_pro')} You need an enterprise license to see unredacted audit logs. diff --git a/frontend/src/routes/(root)/(logged)/workers/+page.svelte b/frontend/src/routes/(root)/(logged)/workers/+page.svelte index ceaabd6109..b6544c75b7 100644 --- a/frontend/src/routes/(root)/(logged)/workers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workers/+page.svelte @@ -135,7 +135,7 @@ } }} options={{ right: 'global cache to s3' }} - disabled={!$enterpriseLicense} + disabled={!$enterpriseLicense || $enterpriseLicense.endsWith('_pro')} />