diff --git a/integrationos-api/src/endpoints/connection_model_definition.rs b/integrationos-api/src/endpoints/connection_model_definition.rs index 9f411ea6..bbe45576 100644 --- a/integrationos-api/src/endpoints/connection_model_definition.rs +++ b/integrationos-api/src/endpoints/connection_model_definition.rs @@ -296,6 +296,7 @@ pub struct CreateRequest { pub is_default_crud_mapping: Option, pub mapping: Option, pub paths: Option, + pub supported: Option, } impl HookExt for CreateRequest {} @@ -344,6 +345,7 @@ impl RequestExt for CreateRequest { is_default_crud_mapping: self.is_default_crud_mapping, mapping: self.mapping.clone(), record_metadata: Default::default(), + supported: self.supported.unwrap_or(false), }; record.record_metadata.version = self.version.clone(); Some(record) @@ -387,6 +389,10 @@ impl RequestExt for CreateRequest { record.extractor_config.clone_from(&self.extractor_config); record.record_metadata.version = self.version.clone(); + if let Some(supported) = self.supported { + record.supported = supported; + } + record } diff --git a/integrationos-api/tests/api_tests/passthrough_tests.rs b/integrationos-api/tests/api_tests/passthrough_tests.rs index dacda9ea..0c3f7870 100644 --- a/integrationos-api/tests/api_tests/passthrough_tests.rs +++ b/integrationos-api/tests/api_tests/passthrough_tests.rs @@ -68,6 +68,7 @@ async fn test_passthrough_api() { responses: vec![], is_default_crud_mapping: None, mapping: None, + supported: Some(true), }; let create_model_definition_response = server @@ -82,6 +83,28 @@ async fn test_passthrough_api() { assert_eq!(create_model_definition_response.code, StatusCode::OK); + let unverified_create_model_definition_payload = CreateConnectionModelDefinitionRequest { + supported: Some(false), + path: "invoices".to_string(), + ..create_model_definition_payload.clone() + }; + + let create_unverified_model_definition_response = server + .send_request::( + "v1/connection-model-definitions", + Method::POST, + Some(&server.live_key), + Some(&serde_json::to_value(&unverified_create_model_definition_payload).unwrap()), + ) + .await + .unwrap(); + + assert_eq!( + create_unverified_model_definition_response.code, + StatusCode::OK + ); + + // Test a passthrough API call for a verified connection model definition let call_universal_api = server .send_request_with_headers::( "v1/passthrough/customers", @@ -101,13 +124,39 @@ async fn test_passthrough_api() { ), ) .await - .expect("Failed to call universal API"); + .expect("Failed to call passthrough API"); - // assert_eq!(call_universal_api.code, StatusCode::OK); assert_eq!( call_universal_api.data, serde_json::from_str::(&response_body).unwrap() ); + // Test a passthrough API call for an unverified connection model definition + let call_unverified_passthrough_endpoint = server + .send_request_with_headers::( + "v1/passthrough/invoices", + Method::GET, + Some(&server.live_key), + None, + Some( + vec![ + (CONTENT_TYPE.to_string(), "application/json".to_string()), + ( + "x-integrationos-connection-key".to_string(), + connection.key.to_string(), + ), + ] + .into_iter() + .collect(), + ), + ) + .await + .expect("Failed to call the passthrough API"); + + assert_eq!( + call_unverified_passthrough_endpoint.code, + StatusCode::NOT_FOUND + ); + mock.assert_async().await; } diff --git a/integrationos-api/tests/api_tests/test_server/mod.rs b/integrationos-api/tests/api_tests/test_server/mod.rs index 58515888..175aff69 100644 --- a/integrationos-api/tests/api_tests/test_server/mod.rs +++ b/integrationos-api/tests/api_tests/test_server/mod.rs @@ -530,6 +530,7 @@ impl TestServer { ), to_common_model: Some("function mapCrudRequest(data) { return data; }".to_string()), }), + supported: Some(true), }; let res = self diff --git a/integrationos-api/tests/api_tests/unified_tests.rs b/integrationos-api/tests/api_tests/unified_tests.rs index 20f65857..40a32142 100644 --- a/integrationos-api/tests/api_tests/unified_tests.rs +++ b/integrationos-api/tests/api_tests/unified_tests.rs @@ -580,6 +580,7 @@ async fn create_connection_model_definition( responses: vec![], is_default_crud_mapping: None, mapping: Some(mapping.clone()), + supported: Some(true), }; let create_model_definition_response = server diff --git a/integrationos-domain/src/domain/connection/connection_model_definition.rs b/integrationos-domain/src/domain/connection/connection_model_definition.rs index da5f657f..1b7527df 100644 --- a/integrationos-domain/src/domain/connection/connection_model_definition.rs +++ b/integrationos-domain/src/domain/connection/connection_model_definition.rs @@ -48,6 +48,9 @@ pub struct ConnectionModelDefinition { #[serde(flatten, default)] pub record_metadata: RecordMetadata, + + #[serde(default)] + pub supported: bool, } #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize)] diff --git a/integrationos-domain/src/service/client/caller_client.rs b/integrationos-domain/src/service/client/caller_client.rs index f72ed01f..d1a87de3 100644 --- a/integrationos-domain/src/service/client/caller_client.rs +++ b/integrationos-domain/src/service/client/caller_client.rs @@ -171,6 +171,7 @@ mod tests { record_metadata: Default::default(), is_default_crud_mapping: None, mapping: None, + supported: true, }; let client = Client::new(); @@ -244,6 +245,7 @@ mod tests { record_metadata: Default::default(), is_default_crud_mapping: None, mapping: None, + supported: true, }; let client = Client::new(); diff --git a/integrationos-event/tests/mock_destination.rs b/integrationos-event/tests/mock_destination.rs index f00c4ca5..5be442a8 100644 --- a/integrationos-event/tests/mock_destination.rs +++ b/integrationos-event/tests/mock_destination.rs @@ -83,6 +83,7 @@ pub async fn seed_db(config: &EventCoreConfig, base_url: String) -> Id { record_metadata: Default::default(), is_default_crud_mapping: None, mapping: None, + supported: true, }; db.collection("connection-model-definitions") diff --git a/integrationos-unified/src/unified.rs b/integrationos-unified/src/unified.rs index 873b8783..ea578634 100644 --- a/integrationos-unified/src/unified.rs +++ b/integrationos-unified/src/unified.rs @@ -24,7 +24,7 @@ use integrationos_domain::{ hashed_secret::HashedSecret, id::{prefix::IdPrefix, Id}, prelude::{CryptoExt, MongoStore, TimedExt}, - Connection, ErrorMeta, IntegrationOSError, Store, + ApplicationError, Connection, ErrorMeta, IntegrationOSError, Store, }; use js_sandbox_ios::Script; use moka::future::Cache; @@ -973,6 +973,13 @@ impl UnifiedDestination { Err(e) => Err(InternalError::connection_error(e.message().as_ref(), None)), }?; + if !config.supported { + return Err(ApplicationError::not_found( + "Supported Connection Model Definition", + None, + )); + } + let secret = self .secrets_cache .try_get_with_by_ref(&connection, async {