diff --git a/Cargo.lock b/Cargo.lock index 5e0fd46574..a810f8e361 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,6 +33,41 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" +dependencies = [ + "aead", + "aes", + "cipher 0.3.0", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.8.11" @@ -613,7 +648,7 @@ checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" dependencies = [ "base64 0.22.1", "blowfish 0.9.1", - "getrandom", + "getrandom 0.2.15", "subtle", "zeroize", ] @@ -923,6 +958,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + [[package]] name = "cipher" version = "0.4.4" @@ -1204,6 +1248,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" +dependencies = [ + "cipher 0.3.0", +] + [[package]] name = "ctrlc" version = "3.4.5" @@ -1214,6 +1267,19 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "darling" version = "0.14.4" @@ -1479,6 +1545,12 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "dotenvy" version = "0.15.7" @@ -1491,6 +1563,29 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" version = "1.13.0" @@ -1849,6 +1944,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -1858,10 +1964,20 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.31.1" @@ -2200,6 +2316,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if", + "libc", + "windows 0.52.0", +] + [[package]] name = "htpasswd-verify" version = "0.3.0" @@ -2814,6 +2941,38 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "keygen-rs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff9289f9aff6746dbdb6c15382e26fb949ddb69386f4999387026094276039c" +dependencies = [ + "aes-gcm", + "async-trait", + "base64 0.21.7", + "chrono", + "dotenv", + "ed25519-dalek", + "futures", + "futures-timer", + "hex", + "hostname", + "lazy_static", + "log", + "machine-uid", + "mockito", + "num_cpus", + "rand 0.7.3", + "reqwest 0.11.27", + "serde", + "serde_json", + "serde_urlencoded", + "sha2 0.10.8", + "thiserror 1.0.69", + "tokio", + "url", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -3118,6 +3277,16 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "machine-uid" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4506fa0abb0a2ea93f5862f55973da0a662d2ad0e98f337a1c5aac657f0892" +dependencies = [ + "libc", + "winreg 0.52.0", +] + [[package]] name = "machineid-rs" version = "1.2.4" @@ -3308,7 +3477,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -3320,10 +3489,28 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi 0.3.9", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] +[[package]] +name = "mockito" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f9fece9bd97ab74339fe19f4bcaf52b76dcc18e5364c7977c1838f76b38de9" +dependencies = [ + "assert-json-diff", + "colored", + "httparse", + "lazy_static", + "log", + "rand 0.8.5", + "regex", + "serde_json", + "serde_urlencoded", + "similar", +] + [[package]] name = "moka" version = "0.12.8" @@ -3727,7 +3914,7 @@ dependencies = [ "opentelemetry 0.23.0", "ordered-float 4.5.0", "percent-encoding", - "rand", + "rand 0.8.5", "serde_json", "thiserror 1.0.69", "tokio", @@ -4008,6 +4195,27 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "postgrest" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a966c650b47a064e7082170b4be74fca08c088d893244fc4b70123e3c1f3ee7" +dependencies = [ + "reqwest 0.11.27", +] + [[package]] name = "posthog-rs" version = "0.2.3" @@ -4395,7 +4603,7 @@ dependencies = [ "byteorder", "hmac 0.10.1", "md-5 0.9.1", - "rand", + "rand 0.8.5", "sha-1 0.9.8", "sha2 0.9.9", ] @@ -4410,7 +4618,7 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi", ] @@ -4460,8 +4668,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", - "getrandom", - "rand", + "getrandom 0.2.15", + "rand 0.8.5", "ring", "rustc-hash 2.0.0", "rustls 0.23.19", @@ -4496,6 +4704,19 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -4503,8 +4724,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -4514,7 +4745,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -4523,7 +4763,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -4570,7 +4819,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 1.0.69", ] @@ -4779,7 +5028,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -5346,6 +5595,12 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + [[package]] name = "similar" version = "2.6.0" @@ -5633,7 +5888,7 @@ dependencies = [ "futures-timer", "futures-util", "genai", - "getrandom", + "getrandom 0.2.15", "headers", "htpasswd-verify", "http 0.2.12", @@ -5677,7 +5932,7 @@ dependencies = [ "prost-reflect 0.14.3", "protox 0.7.1", "protox-parse 0.7.0", - "rand", + "rand 0.8.5", "regex", "reqwest 0.11.27", "reqwest-middleware", @@ -5698,6 +5953,7 @@ dependencies = [ "strum", "strum_macros", "tailcall-chunk", + "tailcall-enterprise", "tailcall-fixtures", "tailcall-hasher", "tailcall-http-cache", @@ -5772,6 +6028,19 @@ dependencies = [ "worker", ] +[[package]] +name = "tailcall-enterprise" +version = "0.1.0" +dependencies = [ + "keygen-rs", + "postgrest", + "reqwest 0.11.27", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", +] + [[package]] name = "tailcall-fixtures" version = "0.1.0" @@ -6396,7 +6665,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util", @@ -6599,6 +6868,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -6666,7 +6945,7 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ - "getrandom", + "getrandom 0.2.15", "wasm-bindgen", ] @@ -6707,6 +6986,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -6938,6 +7223,16 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.57.0" @@ -7283,6 +7578,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winsafe" version = "0.0.19" @@ -7484,6 +7789,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] [[package]] name = "zerovec" diff --git a/Cargo.toml b/Cargo.toml index 68f25713f8..90e6114793 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ tailcall-http-cache = { path = "tailcall-http-cache", optional = true } tailcall-version = { path = "./tailcall-version", optional = true } genai = { git = "https://github.com/laststylebender14/rust-genai.git", rev = "63a542ce20132503c520f4e07108e0d768f243c3", optional = true } ctrlc = { version = "3.4.5", optional = true } +tailcall-enterprise = { path = "./tailcall-enterprise", optional = true } # dependencies safe for wasm: @@ -237,6 +238,7 @@ cli = [ "dep:tailcall-version", "dep:genai", "dep:ctrlc", + "dep:tailcall-enterprise", ] # Feature flag to enable all default features. @@ -262,7 +264,8 @@ members = [ "tailcall-wasm", "tailcall-hasher", "tailcall-http-cache", - "tailcall-version", + "tailcall-version", + "tailcall-enterprise", ] # Boost execution_spec snapshot diffing performance diff --git a/src/cli/tc/start.rs b/src/cli/tc/start.rs index b154ed0ccb..80ff9d47d2 100644 --- a/src/cli/tc/start.rs +++ b/src/cli/tc/start.rs @@ -1,4 +1,6 @@ use anyhow::Result; +use tailcall_enterprise::Enterprise; +use tracing::info; use super::helpers::log_endpoint_set; use crate::cli::fmt::Fmt; @@ -12,6 +14,16 @@ pub(super) async fn start_command( let config_module = config_reader.read_all(&file_paths).await?; log_endpoint_set(&config_module.extensions().endpoint_set); Fmt::log_n_plus_one(false, config_module.config()); + + // config module understand the configuration and the features enabled in the + // configuration. + if config_module.is_enterprise_features_enabled() { + let enterprise = Enterprise::try_new().await?; + if enterprise.is_validated() { + info!("TAILCALL_TOKEN validated successfully. Enabling all enterprise features") + } + } + let server = Server::new(config_module); server.fork_start().await?; Ok(()) diff --git a/src/core/config/config_module.rs b/src/core/config/config_module.rs index b7c617ca84..f6e747b330 100644 --- a/src/core/config/config_module.rs +++ b/src/core/config/config_module.rs @@ -6,6 +6,7 @@ use prost_reflect::prost_types::{FileDescriptorProto, FileDescriptorSet}; use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use tailcall_valid::{Valid, Validator}; +use super::LinkType; use crate::core::config::Config; use crate::core::macros::MergeRight; use crate::core::merge_right::MergeRight; @@ -53,6 +54,17 @@ impl ConfigModule { ConfigModule { cache: Cache::from(config), extensions } } + /// Identifies if an enterprise feature is being used + pub fn is_enterprise_features_enabled(&self) -> bool { + let js_capability_enabled = self + .config() + .links + .iter() + .any(|link| matches!(link.type_of, LinkType::Script)); + let telemetry_capability_enabled = self.config().telemetry.is_enabled(); + js_capability_enabled || telemetry_capability_enabled + } + pub fn set_extensions(mut self, extensions: Extensions) -> Self { self.extensions = extensions; self diff --git a/src/core/config/directives/telemetry.rs b/src/core/config/directives/telemetry.rs index 108ff2aab3..dc3533728f 100644 --- a/src/core/config/directives/telemetry.rs +++ b/src/core/config/directives/telemetry.rs @@ -97,6 +97,10 @@ pub struct Telemetry { } impl Telemetry { + pub fn is_enabled(&self) -> bool { + self.export.is_some() + } + pub fn merge_right(mut self, other: Self) -> Self { self.export = match (&self.export, other.export) { (None, None) => None, diff --git a/tailcall-enterprise/Cargo.toml b/tailcall-enterprise/Cargo.toml new file mode 100644 index 0000000000..2214ec97be --- /dev/null +++ b/tailcall-enterprise/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "tailcall-enterprise" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { workspace = true } +reqwest = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +thiserror = { workspace = true } +postgrest = "1.6.0" +keygen-rs = "0.3.1" \ No newline at end of file diff --git a/tailcall-enterprise/src/enterprise.rs b/tailcall-enterprise/src/enterprise.rs new file mode 100644 index 0000000000..32291c0387 --- /dev/null +++ b/tailcall-enterprise/src/enterprise.rs @@ -0,0 +1,123 @@ +#![allow(dead_code)] +use std::env; + +use keygen_rs::config::KeygenConfig; +use keygen_rs::errors::Error; +use postgrest::Postgrest; +use serde::Deserialize; +use thiserror::Error; + +const TOKEN_NAME: &str = "TAILCALL_TOKEN"; + +// Supabase configurations +const TABLE_NAME: &str = "---Add-Table-Name-Here---"; +const ANON_KEY: &str = "---Add-Anonymous-Key-Here---"; +const API_URL: &str = "---Add-Api-Url-Here---"; + +#[derive(Error, Debug)] +pub enum EnterpriseError { + #[error("TAILCALL_TOKEN is not provided. Please connect via https://tailcall.run/contact/ if you haven't already got a token.")] + TokenNotProvided, + #[error("Failed to fetch public key: {0}")] + PublicKeyFetchError(String), + #[error("Failed to parse public key: {0}")] + PublicKeyParsingError(String), + #[error(transparent)] + KeygenError(#[from] Box), + #[error(transparent)] + DatabaseClientError(#[from] reqwest::Error), +} + +#[derive(Debug)] +pub struct Enterprise { + license_key: Option, + config: Option, +} + +#[derive(Deserialize, Debug)] +struct KeygenData { + public_key: String, + account: String, + product: String, + api_url: String, + api_version: String, + api_prefix: String, +} + +impl From for KeygenConfig { + fn from(data: KeygenData) -> Self { + KeygenConfig { + public_key: Some(data.public_key), + account: data.account, + product: data.product, + api_url: data.api_url, + api_version: data.api_version, + api_prefix: data.api_prefix, + ..Default::default() + } + } +} + +impl Enterprise { + pub fn is_validated(&self) -> bool { + self.config.is_some() && self.license_key.is_some() + } + + pub async fn try_new() -> Result { + match env::var(TOKEN_NAME) { + Ok(signed_key) => { + let keygen_data = Self::fetch_public_key().await?; + let mut config: KeygenConfig = keygen_data.into(); + config.license_key = Some(signed_key.clone()); + keygen_rs::config::set_config(config); + let _signed_key_result = + keygen_rs::verify(keygen_rs::license::SchemeCode::Ed25519Sign, &signed_key) + .map_err(|e| match e { + Error::LicenseKeyMissing => EnterpriseError::TokenNotProvided, + _ => EnterpriseError::KeygenError(Box::new(e)), + })?; + Ok(Self { + license_key: Some(signed_key), + config: Some(keygen_rs::config::get_config()), + }) + } + Err(_) => Err(EnterpriseError::TokenNotProvided), + } + } + + async fn fetch_public_key() -> Result { + let client = Postgrest::new(API_URL).insert_header("apiKey", ANON_KEY); + // pick the latest key from the database. + let result = client + .from(TABLE_NAME) + .select("*") + .order("id.desc") + .limit(1) + .single() + .execute() + .await?; + let body = result.json::().await?; + Ok(body) + } +} + +#[cfg(test)] +mod tests { + use std::env; + + use super::*; + + #[tokio::test] + async fn test_no_token_provided() { + env::remove_var(TOKEN_NAME); + let result = Enterprise::try_new().await; + assert!(result.is_err()); + } + + #[tokio::test] + async fn test_invalid_token() { + env::set_var(TOKEN_NAME, "invalid-token"); + let result = Enterprise::try_new().await; + assert!(result.is_err()); + } +} diff --git a/tailcall-enterprise/src/lib.rs b/tailcall-enterprise/src/lib.rs new file mode 100644 index 0000000000..baa021b12a --- /dev/null +++ b/tailcall-enterprise/src/lib.rs @@ -0,0 +1,3 @@ +mod enterprise; + +pub use enterprise::Enterprise;