diff --git a/Cargo.lock b/Cargo.lock index b34feb7..ab8e221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,9 +405,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", @@ -2099,6 +2099,7 @@ dependencies = [ "actix-web", "actix-web-lab", "anyhow", + "async-trait", "chrono", "dotenvy", "envconfig", diff --git a/Cargo.toml b/Cargo.toml index d268f52..d0f95d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ actix-governor = "0.5.0" actix-web = "4.5.1" actix-web-lab = "0.20.2" anyhow = "1.0.79" +async-trait = "0.1.80" chrono = { version = "0.4.33", features = ["serde"] } dotenvy = "0.15.7" envconfig = "0.10.0" diff --git a/src/algebra/mod.rs b/src/algebra/mod.rs index 2494b45..291bcdc 100644 --- a/src/algebra/mod.rs +++ b/src/algebra/mod.rs @@ -1,48 +1,11 @@ mod parameter; mod refresh; +mod storage; mod token; mod trigger; pub use parameter::*; pub use refresh::*; +pub use storage::*; pub use token::*; pub use trigger::*; - -use chrono::{DateTime, Utc}; -use integrationos_domain::{ - algebra::{MongoStore, StoreExt}, - Connection, Id, IntegrationOSError, -}; -use mongodb::bson::doc; - -pub async fn get_connections_to_refresh( - collection: &MongoStore, - refresh_before: &DateTime, - refresh_after: &DateTime, -) -> Result, IntegrationOSError> { - collection - .get_many( - Some(doc! { - "oauth.enabled.expires_at": doc! { - "$gt": refresh_before.timestamp(), - "$lte": refresh_after.timestamp(), - }, - }), - None, - None, - None, - None, - ) - .await -} - -pub async fn get_connection_to_trigger( - collection: &MongoStore, - id: Id, -) -> Result, IntegrationOSError> { - collection - .get_one(doc! { - "_id": id.to_string(), - }) - .await -} diff --git a/src/algebra/parameter.rs b/src/algebra/parameter.rs index 4eab546..dccaf89 100644 --- a/src/algebra/parameter.rs +++ b/src/algebra/parameter.rs @@ -13,13 +13,13 @@ use std::{ }; use tracing::warn; -pub trait Parameter { +pub trait ParameterExt { fn headers(&self, computation: Option<&Computation>) -> Result, Error>; fn body(&self, secret: &OAuthSecret) -> Result, Error>; fn query(&self, computation: Option<&Computation>) -> Result, Error>; } -impl Parameter for ConnectionOAuthDefinition { +impl ParameterExt for ConnectionOAuthDefinition { fn headers(&self, computation: Option<&Computation>) -> Result, Error> { headers(self, computation) } diff --git a/src/algebra/refresh.rs b/src/algebra/refresh.rs index a82f735..ffcd8db 100644 --- a/src/algebra/refresh.rs +++ b/src/algebra/refresh.rs @@ -1,5 +1,6 @@ -use crate::prelude::{ - get_connections_to_refresh, Query, Refresh, StatefulActor, Trigger, TriggerActor, Unit, +use crate::{ + algebra::{StorageExt, TriggerActor}, + domain::{Query, Refresh, StatefulActor, Trigger, Unit}, }; use actix::prelude::*; use chrono::{Duration, Utc}; @@ -66,9 +67,9 @@ impl Handler for RefreshActor { let state = self.state.clone(); Box::pin(async move { - let connections = - get_connections_to_refresh(&connections_store, &refresh_before, &refresh_after) - .await?; + let connections = connections_store + .get_by(&refresh_before, &refresh_after) + .await?; tracing::info!("Found {} connections to refresh", connections.len()); diff --git a/src/algebra/storage.rs b/src/algebra/storage.rs new file mode 100644 index 0000000..4dba38e --- /dev/null +++ b/src/algebra/storage.rs @@ -0,0 +1,45 @@ +use async_trait::async_trait; +use chrono::{DateTime, Utc}; +use integrationos_domain::{Connection, Id, IntegrationOSError, MongoStore, StoreExt}; +use mongodb::bson::doc; + +#[async_trait] +pub trait StorageExt { + async fn get_by( + &self, + refresh_before: &DateTime, + refresh_after: &DateTime, + ) -> Result, IntegrationOSError>; + + async fn get(&self, id: Id) -> Result, IntegrationOSError>; +} + +#[async_trait] +impl StorageExt for MongoStore { + async fn get_by( + &self, + refresh_before: &DateTime, + refresh_after: &DateTime, + ) -> Result, IntegrationOSError> { + self.get_many( + Some(doc! { + "oauth.enabled.expires_at": doc! { + "$gt": refresh_before.timestamp(), + "$lte": refresh_after.timestamp(), + }, + }), + None, + None, + None, + None, + ) + .await + } + + async fn get(&self, id: Id) -> Result, IntegrationOSError> { + self.get_one(doc! { + "_id": id.to_string(), + }) + .await + } +} diff --git a/src/algebra/token.rs b/src/algebra/token.rs index b09d570..45e3309 100644 --- a/src/algebra/token.rs +++ b/src/algebra/token.rs @@ -1,17 +1,17 @@ -use crate::prelude::Config; +use crate::service::Configuration; use chrono::{Duration, Utc}; use integrationos_domain::{Claims, IntegrationOSError as Error, InternalError}; use jsonwebtoken::{encode, EncodingKey, Header}; -pub trait TokenGenerator { - fn generate(&self, configuration: Config, expiration: i64) -> Result; +pub trait TokenExt { + fn generate(&self, configuration: Configuration, expiration: i64) -> Result; } #[derive(Debug, Default)] -pub struct JwtTokenGenerator; +pub struct Token; -impl TokenGenerator for JwtTokenGenerator { - fn generate(&self, configuration: Config, expiration: i64) -> Result { +impl TokenExt for Token { + fn generate(&self, configuration: Configuration, expiration: i64) -> Result { let key = configuration.server().admin_secret(); let key = key.as_bytes(); let key = EncodingKey::from_secret(key); diff --git a/src/algebra/trigger.rs b/src/algebra/trigger.rs index 695a359..780d2de 100644 --- a/src/algebra/trigger.rs +++ b/src/algebra/trigger.rs @@ -1,5 +1,6 @@ -use super::Parameter; -use crate::prelude::{Outcome, Trigger}; +use crate::domain::{Outcome, Trigger}; + +use super::ParameterExt; use actix::prelude::*; use chrono::Duration; use integrationos_domain::{ @@ -256,8 +257,8 @@ impl Handler for TriggerActor { Outcome::success(id.to_string().as_str(), json!({ "id": id.to_string() })) } Err(e) => Outcome::failure( - msg.connection().id.to_string().as_str(), - json!({ "error": e.to_string() }), + e, + json!({ "connectionId": msg.connection().id.to_string() }), ), } }; diff --git a/src/domain/mod.rs b/src/domain/mod.rs index 8e8c94a..3bb1e90 100644 --- a/src/domain/mod.rs +++ b/src/domain/mod.rs @@ -9,3 +9,9 @@ pub use query::*; pub use refresh::*; pub use state::*; pub use trigger::*; + +use futures::Future; +use std::pin::Pin; + +pub type Unit = (); +pub type Task = Pin + Send + Sync>>; diff --git a/src/domain/outcome.rs b/src/domain/outcome.rs index 0a030cc..f0955de 100644 --- a/src/domain/outcome.rs +++ b/src/domain/outcome.rs @@ -1,11 +1,19 @@ -use serde::{Deserialize, Serialize}; +use integrationos_domain::IntegrationOSError; +use serde::Serialize; use serde_json::Value; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] +#[serde(tag = "type")] pub enum Outcome { - Success { message: String, metadata: Value }, - Failure { message: String, metadata: Value }, + Success { + message: String, + metadata: Value, + }, + Failure { + error: IntegrationOSError, + metadata: Value, + }, } impl Outcome { @@ -16,10 +24,7 @@ impl Outcome { } } - pub fn failure(message: &str, metadata: Value) -> Self { - Self::Failure { - message: message.to_string(), - metadata, - } + pub fn failure(error: IntegrationOSError, metadata: Value) -> Self { + Self::Failure { error, metadata } } } diff --git a/src/domain/refresh.rs b/src/domain/refresh.rs index fe1bb26..d72740b 100644 --- a/src/domain/refresh.rs +++ b/src/domain/refresh.rs @@ -1,4 +1,4 @@ -use crate::prelude::Unit; +use crate::domain::Unit; use actix::prelude::*; use integrationos_domain::error::IntegrationOSError as Error; diff --git a/src/domain/trigger.rs b/src/domain/trigger.rs index 4cc8082..739fde2 100644 --- a/src/domain/trigger.rs +++ b/src/domain/trigger.rs @@ -1,4 +1,4 @@ -use crate::prelude::Outcome; +use crate::domain::Outcome; use actix::prelude::*; use integrationos_domain::Connection; diff --git a/src/lib.rs b/src/lib.rs index 3284a4b..1cd821d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,15 +2,10 @@ mod algebra; mod domain; mod service; -pub mod prelude { - pub use super::algebra::*; - pub use super::domain::*; - pub use super::service::*; +pub use algebra::*; +pub use domain::*; +pub use service::*; - pub type Unit = (); -} - -use crate::prelude::{AppState, Config, Refresh, Tracer, Unit}; use actix_cors::Cors; use actix_governor::{Governor, GovernorConfigBuilder}; use actix_web::{ @@ -20,14 +15,10 @@ use actix_web::{ }; use actix_web_lab::middleware::from_fn; use anyhow::Context; -use futures::Future; -use prelude::{admin_middleware, get_state, health_check, sensitive_middleware, trigger_refresh}; -use std::{net::TcpListener, pin::Pin, time::Duration}; +use std::{net::TcpListener, time::Duration}; pub const PREFIX: &str = "/v1"; -pub const ADMIN_PREFIX: &str = "/admin"; pub const INTEGRATION_PREFIX: &str = "/integration"; -type Task = Pin + Send + Sync>>; pub struct Application { port: u16, @@ -36,7 +27,7 @@ pub struct Application { } impl Application { - pub async fn start(configuration: &Config) -> Result { + pub async fn start(configuration: &Configuration) -> Result { tracing::info!( "Starting application with configuration: {}{:#?}{}", "\n", @@ -100,7 +91,7 @@ impl Application { async fn run( listener: TcpListener, - configuration: Config, + configuration: Configuration, state: AppState, ) -> Result { let governor = GovernorConfigBuilder::default() @@ -123,15 +114,11 @@ async fn run( .max_age(3600), ) .wrap(Governor::new(&governor)) - .service( - scope(&(PREFIX.to_owned() + ADMIN_PREFIX)) // /v1/admin - .wrap(from_fn(sensitive_middleware)) - .service(get_state), - ) .service( scope(&(PREFIX.to_owned() + INTEGRATION_PREFIX)) // /v1/integration - .wrap(from_fn(admin_middleware)) - .service(trigger_refresh), + .wrap(from_fn(auth_middleware)) + .service(trigger_refresh) + .service(get_state), ) .service(scope(PREFIX).service(health_check)) // /v1 .app_data(Data::new(state.clone())) diff --git a/src/main.rs b/src/main.rs index f1c7c9f..59d4791 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,6 @@ use dotenvy::dotenv; -use oauth_api::{ - prelude::{get_subscriber, init_subscriber, Config, OAuthConfig, ServerConfig}, - Application, -}; +use integrationos_domain::telemetry::{get_subscriber, init_subscriber}; +use oauth_api::{Application, Configuration, OAuthConfig, ServerConfig}; #[actix_web::main] async fn main() -> anyhow::Result<()> { @@ -13,7 +11,7 @@ async fn main() -> anyhow::Result<()> { let oauth = OAuthConfig::load().expect("Failed to read configuration."); let server = ServerConfig::load().expect("Failed to read configuration."); - let configuration = Config::new(oauth, server); + let configuration = Configuration::new(oauth, server); let address = configuration.server().app_url().to_string(); let application = Application::start(&configuration).await?; diff --git a/src/service/configuration/mod.rs b/src/service/configuration/mod.rs index e2b6a2e..6869dcb 100644 --- a/src/service/configuration/mod.rs +++ b/src/service/configuration/mod.rs @@ -154,12 +154,12 @@ impl ServerConfig { } #[derive(Clone)] -pub struct Config { +pub struct Configuration { oauth: OAuthConfig, server: ServerConfig, } -impl Debug for Config { +impl Debug for Configuration { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let _ = f .debug_struct("OAuthConfig") @@ -185,7 +185,7 @@ impl Debug for Config { } } -impl Config { +impl Configuration { pub fn new(oauth: OAuthConfig, server: ServerConfig) -> Self { Self { oauth, server } } @@ -296,7 +296,7 @@ impl From> for ServerConfig { } } -impl From> for Config { +impl From> for Configuration { fn from(value: HashMap<&str, &str>) -> Self { let oauth = OAuthConfig::from(value.clone()); let server = ServerConfig::from(value); diff --git a/src/service/http/mod.rs b/src/service/http/mod.rs index 891ba61..3fda6fd 100644 --- a/src/service/http/mod.rs +++ b/src/service/http/mod.rs @@ -1,10 +1,10 @@ -mod admin; +mod private; mod public; -pub use admin::*; +pub use private::*; pub use public::*; -use crate::prelude::AppState; +use super::AppState; use actix_web::{ body::MessageBody, dev::{ServiceRequest, ServiceResponse}, @@ -51,28 +51,7 @@ where } } -pub async fn sensitive_middleware( - req: ServiceRequest, - next: Next, -) -> Result, ActixWebError> { - let state = req.app_data::>(); - let state = match state { - None => return Err(ErrorUnauthorized("No state found")), - Some(state) => state, - }; - - let extracted_info = extract_admin_info(&req, state); - - match extracted_info { - Ok(claims) => { - req.extensions_mut().insert(claims.to_owned()); - next.call(req).await - } - Err(err) => Err(ErrorUnauthorized(err)), - } -} - -pub async fn admin_middleware( +pub async fn auth_middleware( req: ServiceRequest, next: Next, ) -> Result, ActixWebError> { @@ -83,7 +62,7 @@ pub async fn admin_middleware( }; let event_access = extract_event_info(&req, state).await; - let claims = extract_admin_info(&req, state); + let claims = claims(&req, state); match (event_access, claims) { (Ok(event_access), Ok(claims)) => { @@ -95,10 +74,7 @@ pub async fn admin_middleware( } } -fn extract_admin_info( - req: &ServiceRequest, - state: &Data, -) -> Result { +fn claims(req: &ServiceRequest, state: &Data) -> Result { let token = req .headers() .get(state.configuration().server().admin_header()) diff --git a/src/service/http/admin/mod.rs b/src/service/http/private/mod.rs similarity index 50% rename from src/service/http/admin/mod.rs rename to src/service/http/private/mod.rs index 278e0b5..f6e3670 100644 --- a/src/service/http/admin/mod.rs +++ b/src/service/http/private/mod.rs @@ -1,3 +1,5 @@ mod refresh; +mod trigger; pub use refresh::*; +pub use trigger::*; diff --git a/src/service/http/admin/refresh.rs b/src/service/http/private/refresh.rs similarity index 78% rename from src/service/http/admin/refresh.rs rename to src/service/http/private/refresh.rs index 3dc05f3..89e57ac 100644 --- a/src/service/http/admin/refresh.rs +++ b/src/service/http/private/refresh.rs @@ -1,5 +1,5 @@ -use crate::prelude::Query as RefreshQuery; -use crate::prelude::{AppState, ResponseType, ServerResponse}; +use crate::domain::Query; +use crate::service::{AppState, ResponseType, ServerResponse}; use actix_web::{get, web::Data, HttpResponse}; use integrationos_domain::error::IntegrationOSError as Error; use integrationos_domain::InternalError; @@ -9,7 +9,7 @@ use integrationos_domain::InternalError; pub async fn get_state(state: Data) -> Result { let response = state .refresh_actor - .send(RefreshQuery) + .send(Query) .await .map_err(|e| InternalError::io_err(e.to_string().as_str(), None))?; diff --git a/src/service/http/public/trigger.rs b/src/service/http/private/trigger.rs similarity index 70% rename from src/service/http/public/trigger.rs rename to src/service/http/private/trigger.rs index cfd551d..7b462f6 100644 --- a/src/service/http/public/trigger.rs +++ b/src/service/http/private/trigger.rs @@ -1,5 +1,7 @@ -use crate::prelude::{ - get_connection_to_trigger, AppState, ResponseType, ServerResponse, Trigger, TriggerActor, +use crate::{ + algebra::{StorageExt, TriggerActor}, + domain::{Outcome, Trigger}, + service::{AppState, ResponseType, ServerResponse}, }; use actix::Actor; use actix_web::{ @@ -10,6 +12,7 @@ use actix_web::{ use integrationos_domain::{ error::IntegrationOSError as Error, ApplicationError, Id, InternalError, }; +use reqwest::StatusCode; use serde_json::json; use tracing_actix_web::RequestId; @@ -20,7 +23,10 @@ pub async fn trigger_refresh( state: Data, id: Path, ) -> Result { - let connection = get_connection_to_trigger(state.connections(), *id) + let id = id.into_inner(); + let connection = state + .connections() + .get(id) .await? .ok_or(ApplicationError::not_found( format!("Connection with id {} not found", id).as_str(), @@ -51,5 +57,14 @@ pub async fn trigger_refresh( "outcome": outcome, }); - Ok(ServerResponse::from(ResponseType::Trigger, json, 200)) + let status: StatusCode = match outcome { + Outcome::Success { .. } => StatusCode::OK, + Outcome::Failure { error, .. } => error.into(), + }; + + Ok(ServerResponse::from( + ResponseType::Trigger, + json, + status.into(), + )) } diff --git a/src/service/http/public/health.rs b/src/service/http/public/health.rs index ea85250..4797970 100644 --- a/src/service/http/public/health.rs +++ b/src/service/http/public/health.rs @@ -1,6 +1,7 @@ -use crate::prelude::{ResponseType, ServerResponse}; use actix_web::{get, HttpResponse}; +use crate::service::{ResponseType, ServerResponse}; + #[get("/health_check")] pub async fn health_check() -> HttpResponse { ServerResponse::from(ResponseType::Health, "I'm alive!".to_string(), 200) diff --git a/src/service/http/public/mod.rs b/src/service/http/public/mod.rs index de0a99f..96b5207 100644 --- a/src/service/http/public/mod.rs +++ b/src/service/http/public/mod.rs @@ -1,5 +1,3 @@ mod health; -mod trigger; pub use health::*; -pub use trigger::*; diff --git a/src/service/mod.rs b/src/service/mod.rs index 9df8c66..66cbffc 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,7 +4,7 @@ mod http; pub use configuration::*; pub use http::*; -use crate::prelude::RefreshActor; +use crate::algebra::RefreshActor; use actix::{Addr, Supervisor}; use integrationos_domain::{ algebra::MongoStore, client::secrets_client::SecretsClient, @@ -19,7 +19,7 @@ use tokio::time::timeout; #[derive(Clone, Debug)] pub struct AppState { - configuration: Config, + configuration: Configuration, cache: Cache>, client: Client, secrets: Arc, @@ -30,7 +30,7 @@ pub struct AppState { } impl AppState { - pub async fn try_from(config: Config) -> Result { + pub async fn try_from(config: Configuration) -> Result { let client = Client::builder() .timeout(Duration::from_millis(config.server().timeout())) .build() @@ -95,7 +95,7 @@ impl AppState { }) } - pub fn configuration(&self) -> &Config { + pub fn configuration(&self) -> &Configuration { &self.configuration } diff --git a/tests/http/trigger.rs b/tests/http/trigger.rs index 00daa1a..55360cf 100644 --- a/tests/http/trigger.rs +++ b/tests/http/trigger.rs @@ -1,6 +1,7 @@ use crate::suite::TestApp; use integrationos_domain::{prefix::IdPrefix, Id}; -use oauth_api::prelude::{JwtTokenGenerator, TokenGenerator}; +use mark_flaky_tests::flaky; +use oauth_api::{Token, TokenExt}; use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use std::collections::HashMap; use uuid::Uuid; @@ -17,13 +18,12 @@ async fn returns_401_for_missing_headers() { } #[actix::test] -#[ignore = "BsonSerialization is failing with UnsignedIntegerExceededRange on CI"] async fn returns_404_for_invalid_prefix_id() { // Arrange let application = TestApp::spawn(HashMap::new()).await; let event_access = application.insert_event_access().await; let event_access_token = event_access.access_key; - let token = JwtTokenGenerator + let token = Token .generate(application.configuration().clone(), 1) .expect("Failed to generate token"); @@ -58,12 +58,11 @@ async fn returns_404_for_invalid_prefix_id() { } #[actix::test] -#[ignore = "BsonSerialization is failing with UnsignedIntegerExceededRange on CI"] async fn returns_401_for_non_existent_event_access() { // Arrange let application = TestApp::spawn(HashMap::new()).await; let event_access = "sk_live_1_Gom7umYOtRPyCbx4o2XNIlM32-2wf2dPI6s7nsdlWeXuhRj1rgDEvFeYAVckQvwG-5IUzRHGWnloNx2fci7IdFcdlTqYAuUuj6QQZPOvS2sxGK4YKnkmS1UFqcXFDCsSYZxASBaqJaBZA1HMEVuv61-cepuCBJccX90hXqQlKZvZ5s0i8hRZszeCA9b3H18paLy7"; - let token = JwtTokenGenerator + let token = Token .generate(application.configuration().clone(), 1) .expect("Failed to generate token"); let headers = HeaderMap::from_iter(vec![ @@ -99,15 +98,14 @@ async fn returns_401_for_non_existent_event_access() { } #[actix::test] -// #[flaky] -#[ignore = "BsonSerialization is failing with UnsignedIntegerExceededRange on CI"] +#[flaky] async fn returns_404_inexistent_event() { // Arrange let application = TestApp::spawn(HashMap::new()).await; let event_access = application.insert_event_access().await; let event_access_token = event_access.access_key; - let token = JwtTokenGenerator + let token = Token .generate(application.configuration().clone(), 1) .expect("Failed to generate token"); diff --git a/tests/suite.rs b/tests/suite.rs index ed9e373..4f6355f 100644 --- a/tests/suite.rs +++ b/tests/suite.rs @@ -3,11 +3,11 @@ use fake::{Fake, Faker}; use integrationos_domain::{ access_key_data::AccessKeyData, access_key_prefix::AccessKeyPrefix, connection_model_definition::ConnectionModelDefinition, encrypted_data::PASSWORD_LENGTH, - environment::Environment, event_access::EventAccess, event_type::EventType, AccessKey, Id, - Store, + environment::Environment, event_access::EventAccess, event_type::EventType, prefix::IdPrefix, + AccessKey, Id, Store, }; use mongodb::{Client as MongoClient, Database}; -use oauth_api::{prelude::Config, Application}; +use oauth_api::Configuration; use once_cell::sync::Lazy; use rand::Rng; use reqwest::{header::HeaderMap, Client}; @@ -17,7 +17,7 @@ use uuid::Uuid; pub struct TestApp { client: Client, address: String, - configuration: Config, + configuration: Configuration, mongo: Database, } @@ -28,13 +28,7 @@ pub static EPOCH: Lazy> = Lazy::new(|| { &NaiveDateTime::from_timestamp_opt(0, 0).expect("Failed to create timestamp"), ) }); -pub static ID: Lazy = Lazy::new(|| { - Id::new_with_uuid( - integrationos_domain::prefix::IdPrefix::ConnectionModelDefinition, - *EPOCH, - Uuid::nil(), - ) -}); +pub static ID: Lazy = Lazy::new(|| Id::now(IdPrefix::ConnectionModelDefinition)); pub static EVENT_ACCESS_PASSWORD: Lazy<[u8; PASSWORD_LENGTH]> = Lazy::new(|| { "32KFFT_i4UpkJmyPwY2TGzgHpxfXs7zS" .as_bytes() @@ -75,10 +69,12 @@ impl TestApp { pub async fn spawn(config: HashMap<&str, &str>) -> Self { use std::collections::hash_map::RandomState; + use oauth_api::Application; + let url = "mongodb://127.0.0.1:27017/?directConnection=true"; let uuid = Uuid::new_v4().to_string(); - let configuration = Config::from( + let configuration = Configuration::from( HashMap::<&str, &str, RandomState>::from_iter([ ("HOST", "localhost"), ("PORT", "0"), @@ -142,7 +138,9 @@ impl TestApp { let access_key = self.access_key_encoded(); event_access.access_key = access_key; - event_access.record_metadata.deleted = false; + event_access.paths = Default::default(); + event_access.throughput = Default::default(); + event_access.record_metadata = Default::default(); let _ = self .mongo @@ -162,7 +160,7 @@ impl TestApp { version: 1, }, data: AccessKeyData { - id: Uuid::new_v4().to_string(), + id: Id::now(IdPrefix::EventAccess).to_string(), namespace: "namespace".to_string(), event_type: "event_type".to_string(), group: "group".to_string(), @@ -188,7 +186,7 @@ impl TestApp { &self.address } - pub fn configuration(&self) -> &Config { + pub fn configuration(&self) -> &Configuration { &self.configuration }