core: type auth profile timestamps
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::{
|
||||
ids::{AuthProfileId, SecretId, WorkspaceId},
|
||||
@@ -56,6 +57,41 @@ pub struct AuthProfile {
|
||||
pub name: String,
|
||||
pub kind: AuthKind,
|
||||
pub config: AuthConfig,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub created_at: OffsetDateTime,
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub updated_at: OffsetDateTime,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
|
||||
use super::{ApiKeyHeaderAuthConfig, AuthConfig, AuthProfile};
|
||||
use crate::{
|
||||
ids::{AuthProfileId, SecretId, WorkspaceId},
|
||||
protocol::AuthKind,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn auth_profile_serializes_timestamps_as_rfc3339() {
|
||||
let profile = AuthProfile {
|
||||
id: AuthProfileId::new("auth_01"),
|
||||
workspace_id: WorkspaceId::new("ws_default"),
|
||||
name: "header".to_owned(),
|
||||
kind: AuthKind::ApiKeyHeader,
|
||||
config: AuthConfig::ApiKeyHeader(ApiKeyHeaderAuthConfig {
|
||||
header_name: "X-Api-Key".to_owned(),
|
||||
secret_id: SecretId::new("secret_01"),
|
||||
}),
|
||||
created_at: OffsetDateTime::parse("2026-03-25T12:00:00Z", &Rfc3339).unwrap(),
|
||||
updated_at: OffsetDateTime::parse("2026-03-25T12:05:00Z", &Rfc3339).unwrap(),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(&profile).unwrap();
|
||||
|
||||
assert_eq!(value["created_at"], json!("2026-03-25T12:00:00Z"));
|
||||
assert_eq!(value["updated_at"], json!("2026-03-25T12:05:00Z"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +264,7 @@ mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use serde_json::json;
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
|
||||
use crate::{
|
||||
auth::{AuthConfig, AuthProfile, BearerAuthConfig},
|
||||
@@ -280,6 +281,10 @@ mod tests {
|
||||
},
|
||||
};
|
||||
|
||||
fn timestamp(value: &str) -> OffsetDateTime {
|
||||
OffsetDateTime::parse(value, &Rfc3339).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rest_target_serializes_with_kind_tag() {
|
||||
let target = Target::Rest(RestTarget {
|
||||
@@ -440,8 +445,8 @@ mod tests {
|
||||
header_name: "Authorization".to_owned(),
|
||||
secret_id: crate::ids::SecretId::new("secret_crm_prod_token"),
|
||||
}),
|
||||
created_at: "2026-03-25T08:00:00Z".to_owned(),
|
||||
updated_at: "2026-03-25T08:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-03-25T08:00:00Z"),
|
||||
updated_at: timestamp("2026-03-25T08:00:00Z"),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(profile).unwrap();
|
||||
|
||||
@@ -389,8 +389,8 @@ impl PostgresRegistry {
|
||||
.bind(&request.profile.name)
|
||||
.bind(serialize_enum_text(&request.profile.kind, "kind")?)
|
||||
.bind(Json(serialize_json_value(&request.profile.config)?))
|
||||
.bind(&request.profile.created_at)
|
||||
.bind(&request.profile.updated_at)
|
||||
.bind(request.profile.created_at)
|
||||
.bind(request.profile.updated_at)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
@@ -409,8 +409,8 @@ impl PostgresRegistry {
|
||||
name,
|
||||
kind,
|
||||
config_json,
|
||||
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"created_at!\",
|
||||
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"updated_at!\"
|
||||
created_at as \"created_at!: OffsetDateTime\",
|
||||
updated_at as \"updated_at!: OffsetDateTime\"
|
||||
from auth_profiles
|
||||
where workspace_id = $1 and id = $2",
|
||||
workspace_id.as_str(),
|
||||
@@ -444,8 +444,8 @@ impl PostgresRegistry {
|
||||
name,
|
||||
kind,
|
||||
config_json,
|
||||
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"created_at!\",
|
||||
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"updated_at!\"
|
||||
created_at as \"created_at!: OffsetDateTime\",
|
||||
updated_at as \"updated_at!: OffsetDateTime\"
|
||||
from auth_profiles
|
||||
where workspace_id = $1
|
||||
order by name asc",
|
||||
|
||||
@@ -750,8 +750,8 @@ fn build_auth_profile(
|
||||
name: String,
|
||||
kind: String,
|
||||
config_json: Value,
|
||||
created_at: String,
|
||||
updated_at: String,
|
||||
created_at: OffsetDateTime,
|
||||
updated_at: OffsetDateTime,
|
||||
) -> Result<AuthProfile, RegistryError> {
|
||||
Ok(AuthProfile {
|
||||
id: crank_core::AuthProfileId::new(id),
|
||||
@@ -1315,8 +1315,8 @@ mod tests {
|
||||
header_name: "X-Api-Key".to_owned(),
|
||||
secret_id: SecretId::new("secret_crank_api_key"),
|
||||
}),
|
||||
created_at: "2026-03-25T12:00:00Z".to_owned(),
|
||||
updated_at: "2026-03-25T12:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
updated_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
};
|
||||
|
||||
registry
|
||||
@@ -1396,8 +1396,8 @@ mod tests {
|
||||
username_secret_id: primary_secret_id.clone(),
|
||||
password_secret_id: secondary_secret_id.clone(),
|
||||
}),
|
||||
created_at: "2026-03-25T12:00:00Z".to_owned(),
|
||||
updated_at: "2026-03-25T12:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
updated_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
};
|
||||
|
||||
registry
|
||||
|
||||
@@ -26,5 +26,6 @@ thiserror.workspace = true
|
||||
axum.workspace = true
|
||||
crank-adapter-grpc = { path = "../crank-adapter-grpc", features = ["test-support"] }
|
||||
futures-util = "0.3"
|
||||
time.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-tungstenite.workspace = true
|
||||
|
||||
@@ -120,9 +120,14 @@ mod tests {
|
||||
BasicAuthConfig, BearerAuthConfig, SecretId, WorkspaceId,
|
||||
};
|
||||
use serde_json::json;
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
|
||||
use crate::{PreparedRequest, auth::ResolvedAuth};
|
||||
|
||||
fn timestamp(value: &str) -> OffsetDateTime {
|
||||
OffsetDateTime::parse(value, &Rfc3339).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn applies_bearer_auth_to_headers() {
|
||||
let auth = ResolvedAuth::from_profile(
|
||||
@@ -135,8 +140,8 @@ mod tests {
|
||||
header_name: "Authorization".to_owned(),
|
||||
secret_id: SecretId::new("secret_token"),
|
||||
}),
|
||||
created_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
updated_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
updated_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
},
|
||||
&BTreeMap::from([(SecretId::new("secret_token"), json!({"token":"abc"}))]),
|
||||
)
|
||||
@@ -163,8 +168,8 @@ mod tests {
|
||||
username_secret_id: SecretId::new("secret_user"),
|
||||
password_secret_id: SecretId::new("secret_pass"),
|
||||
}),
|
||||
created_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
updated_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
updated_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
},
|
||||
&BTreeMap::from([
|
||||
(SecretId::new("secret_user"), json!({"username":"demo"})),
|
||||
@@ -194,8 +199,8 @@ mod tests {
|
||||
header_name: "X-Api-Key".to_owned(),
|
||||
secret_id: SecretId::new("secret_api_key"),
|
||||
}),
|
||||
created_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
updated_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
updated_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
},
|
||||
&BTreeMap::from([(SecretId::new("secret_api_key"), json!("key-123"))]),
|
||||
)
|
||||
@@ -222,8 +227,8 @@ mod tests {
|
||||
param_name: "api_key".to_owned(),
|
||||
secret_id: SecretId::new("secret_api_key"),
|
||||
}),
|
||||
created_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
updated_at: "2026-04-07T00:00:00Z".to_owned(),
|
||||
created_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
updated_at: timestamp("2026-04-07T00:00:00Z"),
|
||||
},
|
||||
&BTreeMap::from([(SecretId::new("secret_api_key"), json!({"value":"key-123"}))]),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user