Public Access
fix: format and lint
This commit is contained in:
@@ -95,17 +95,18 @@ impl ProductHandler {
|
||||
let mapped = self.field_mapper.map_all(entity).await?;
|
||||
|
||||
// Extract name/description from mapped fields or directly from entity metadata
|
||||
let name = mapped.get("name").cloned()
|
||||
let name = mapped
|
||||
.get("name")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(self.extract_name(entity)));
|
||||
let description = mapped.get("description").cloned()
|
||||
.unwrap_or_else(|| {
|
||||
let desc = self.extract_description(entity);
|
||||
if desc.is_empty() {
|
||||
json!(format!("Managed by Charybdis (entity: {})", entity.id))
|
||||
} else {
|
||||
json!(desc)
|
||||
}
|
||||
});
|
||||
let description = mapped.get("description").cloned().unwrap_or_else(|| {
|
||||
let desc = self.extract_description(entity);
|
||||
if desc.is_empty() {
|
||||
json!(format!("Managed by Charybdis (entity: {})", entity.id))
|
||||
} else {
|
||||
json!(desc)
|
||||
}
|
||||
});
|
||||
|
||||
// Build DefectDojo product payload
|
||||
let mut payload = json!({
|
||||
@@ -315,7 +316,10 @@ impl ProductHandler {
|
||||
match &group.spec {
|
||||
Some(Spec::GroupSpec(s)) => s.members.clone(),
|
||||
_ => {
|
||||
warn!("Group '{}' has no GroupSpec — cannot resolve members", owner);
|
||||
warn!(
|
||||
"Group '{}' has no GroupSpec — cannot resolve members",
|
||||
owner
|
||||
);
|
||||
return Ok(resolved_users);
|
||||
}
|
||||
}
|
||||
@@ -382,11 +386,7 @@ impl ProductHandler {
|
||||
}
|
||||
|
||||
/// Assign resolved users as product members in DefectDojo
|
||||
async fn assign_owner_to_product(
|
||||
&self,
|
||||
product_id: i32,
|
||||
owner: &str,
|
||||
) -> Result<Vec<i32>> {
|
||||
async fn assign_owner_to_product(&self, product_id: i32, owner: &str) -> Result<Vec<i32>> {
|
||||
let resolved = self.resolve_owner_to_users(owner).await?;
|
||||
|
||||
if resolved.is_empty() {
|
||||
@@ -471,9 +471,7 @@ impl ProductHandler {
|
||||
fn extract_owner(&self, entity: &Entity) -> Option<String> {
|
||||
use charybdis::charybdis::entities::entity;
|
||||
match &entity.spec {
|
||||
Some(entity::Spec::ComponentSpec(s)) if !s.owner.is_empty() => {
|
||||
Some(s.owner.clone())
|
||||
}
|
||||
Some(entity::Spec::ComponentSpec(s)) if !s.owner.is_empty() => Some(s.owner.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -501,7 +499,10 @@ impl ResourceHandler for ProductHandler {
|
||||
|
||||
// Build annotations to store DefectDojo product ID
|
||||
let mut annotations = HashMap::new();
|
||||
annotations.insert("defectdojo.com/product-id".to_string(), product_id.to_string());
|
||||
annotations.insert(
|
||||
"defectdojo.com/product-id".to_string(),
|
||||
product_id.to_string(),
|
||||
);
|
||||
|
||||
// Auto-create engagement if enabled
|
||||
if self.config.default_engagement.auto_create {
|
||||
@@ -516,7 +517,10 @@ impl ResourceHandler for ProductHandler {
|
||||
.await
|
||||
{
|
||||
Ok(engagement_id) => {
|
||||
annotations.insert("defectdojo.com/engagement-id".to_string(), engagement_id.to_string());
|
||||
annotations.insert(
|
||||
"defectdojo.com/engagement-id".to_string(),
|
||||
engagement_id.to_string(),
|
||||
);
|
||||
info!(
|
||||
"Auto-created engagement {} for product {} (entity: {})",
|
||||
engagement_id, product_id, entity.id
|
||||
@@ -552,7 +556,9 @@ impl ResourceHandler for ProductHandler {
|
||||
}
|
||||
|
||||
// Update only annotations in Charybdis
|
||||
self.repository.update_annotations(&entity.id, annotations).await?;
|
||||
self.repository
|
||||
.update_annotations(&entity.id, annotations)
|
||||
.await?;
|
||||
|
||||
// Don't create a new entity, just return None
|
||||
Ok(None)
|
||||
@@ -571,8 +577,13 @@ impl ResourceHandler for ProductHandler {
|
||||
|
||||
// Update only annotations with product ID
|
||||
let mut annotations = HashMap::new();
|
||||
annotations.insert("defectdojo.com/product-id".to_string(), product_id.to_string());
|
||||
self.repository.update_annotations(&entity.id, annotations).await?;
|
||||
annotations.insert(
|
||||
"defectdojo.com/product-id".to_string(),
|
||||
product_id.to_string(),
|
||||
);
|
||||
self.repository
|
||||
.update_annotations(&entity.id, annotations)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -8,7 +8,9 @@ use charybdis::charybdis::entities::entity::{Metadata, Spec};
|
||||
use charybdis::charybdis::entities::Entity;
|
||||
use charybdis::database::{ensure_schema, EntityRepository};
|
||||
use charybdis::plugins::ResourceHandler;
|
||||
use charybdis_defectdojo::{DefectDojoClient, DefectDojoConfig, EngagementConfig, OwnerResolutionConfig};
|
||||
use charybdis_defectdojo::{
|
||||
DefectDojoClient, DefectDojoConfig, EngagementConfig, OwnerResolutionConfig,
|
||||
};
|
||||
use serde_json::json;
|
||||
use sqlx::PgPool;
|
||||
use std::collections::HashMap;
|
||||
@@ -17,9 +19,11 @@ use wiremock::matchers::{method, path, query_param};
|
||||
use wiremock::{Mock, MockServer, ResponseTemplate};
|
||||
|
||||
async fn setup_db() -> PgPool {
|
||||
let url = std::env::var("DATABASE_URL")
|
||||
.expect("DATABASE_URL must be set for integration tests");
|
||||
let pool = PgPool::connect(&url).await.expect("Failed to connect to test database");
|
||||
let url =
|
||||
std::env::var("DATABASE_URL").expect("DATABASE_URL must be set for integration tests");
|
||||
let pool = PgPool::connect(&url)
|
||||
.await
|
||||
.expect("Failed to connect to test database");
|
||||
ensure_schema(&pool).await.expect("Failed to create schema");
|
||||
|
||||
// Clean up from previous test runs
|
||||
@@ -118,13 +122,11 @@ async fn test_product_creation_on_component_create() {
|
||||
config.owner_resolution.assign_all_members = false;
|
||||
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
@@ -136,7 +138,10 @@ async fn test_product_creation_on_component_create() {
|
||||
|
||||
// Create the entity in the database first (returns entity with real UUID)
|
||||
let entity = make_component_entity("", "payment-api", "team-payments");
|
||||
let entity = repository.create(&entity).await.expect("Failed to create entity");
|
||||
let entity = repository
|
||||
.create(&entity)
|
||||
.await
|
||||
.expect("Failed to create entity");
|
||||
|
||||
// Trigger handler
|
||||
let result = handler.handle_create(&entity).await;
|
||||
@@ -178,13 +183,11 @@ async fn test_product_update_with_existing_product_id() {
|
||||
|
||||
let config = make_config(&mock_server.uri());
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
@@ -196,11 +199,13 @@ async fn test_product_update_with_existing_product_id() {
|
||||
|
||||
// Create entity with existing product-id annotation
|
||||
let mut entity = make_component_entity("", "payment-api", "team-payments");
|
||||
entity.annotations.insert(
|
||||
"defectdojo.com/product-id".to_string(),
|
||||
"42".to_string(),
|
||||
);
|
||||
let entity = repository.create(&entity).await.expect("Failed to create entity");
|
||||
entity
|
||||
.annotations
|
||||
.insert("defectdojo.com/product-id".to_string(), "42".to_string());
|
||||
let entity = repository
|
||||
.create(&entity)
|
||||
.await
|
||||
.expect("Failed to create entity");
|
||||
|
||||
// Trigger update handler
|
||||
let result = handler.handle_update(&entity).await;
|
||||
@@ -228,13 +233,11 @@ async fn test_product_deletion() {
|
||||
|
||||
let config = make_config(&mock_server.uri());
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
@@ -246,11 +249,13 @@ async fn test_product_deletion() {
|
||||
|
||||
// Entity with product-id annotation
|
||||
let mut entity = make_component_entity("", "payment-api", "team-payments");
|
||||
entity.annotations.insert(
|
||||
"defectdojo.com/product-id".to_string(),
|
||||
"42".to_string(),
|
||||
);
|
||||
let entity = repository.create(&entity).await.expect("Failed to create entity");
|
||||
entity
|
||||
.annotations
|
||||
.insert("defectdojo.com/product-id".to_string(), "42".to_string());
|
||||
let entity = repository
|
||||
.create(&entity)
|
||||
.await
|
||||
.expect("Failed to create entity");
|
||||
|
||||
// Trigger delete handler
|
||||
let result = handler.handle_delete(&entity).await;
|
||||
@@ -423,7 +428,10 @@ async fn test_owner_resolution_assigns_product_members() {
|
||||
member_of: vec!["backend-team".to_string()],
|
||||
})),
|
||||
};
|
||||
alice.annotations.insert("keycloak.com/email".to_string(), "alice@example.com".to_string());
|
||||
alice.annotations.insert(
|
||||
"keycloak.com/email".to_string(),
|
||||
"alice@example.com".to_string(),
|
||||
);
|
||||
repository.create(&alice).await.unwrap();
|
||||
|
||||
// Create User "bob" with keycloak email annotation
|
||||
@@ -448,18 +456,19 @@ async fn test_owner_resolution_assigns_product_members() {
|
||||
member_of: vec!["backend-team".to_string()],
|
||||
})),
|
||||
};
|
||||
bob.annotations.insert("keycloak.com/email".to_string(), "bob@example.com".to_string());
|
||||
bob.annotations.insert(
|
||||
"keycloak.com/email".to_string(),
|
||||
"bob@example.com".to_string(),
|
||||
);
|
||||
repository.create(&bob).await.unwrap();
|
||||
|
||||
// Create handlers
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
@@ -489,7 +498,9 @@ async fn test_owner_resolution_assigns_product_members() {
|
||||
);
|
||||
// Owner member IDs should be set
|
||||
assert!(
|
||||
updated.annotations.contains_key("defectdojo.com/owner-member-ids"),
|
||||
updated
|
||||
.annotations
|
||||
.contains_key("defectdojo.com/owner-member-ids"),
|
||||
"Expected owner-member-ids annotation"
|
||||
);
|
||||
}
|
||||
@@ -529,13 +540,11 @@ async fn test_product_creation_without_engagement() {
|
||||
config.default_engagement.auto_create = false;
|
||||
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
@@ -557,7 +566,9 @@ async fn test_product_creation_without_engagement() {
|
||||
updated.annotations.get("defectdojo.com/product-id"),
|
||||
Some(&"55".to_string())
|
||||
);
|
||||
assert!(!updated.annotations.contains_key("defectdojo.com/engagement-id"));
|
||||
assert!(!updated
|
||||
.annotations
|
||||
.contains_key("defectdojo.com/engagement-id"));
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
@@ -583,13 +594,11 @@ async fn test_product_creation_handles_api_error() {
|
||||
|
||||
let config = make_config(&mock_server.uri());
|
||||
let client = DefectDojoClient::new(mock_server.uri(), "test-token".to_string()).unwrap();
|
||||
let engagement_handler = Arc::new(
|
||||
charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
),
|
||||
);
|
||||
let engagement_handler = Arc::new(charybdis_defectdojo::handlers::EngagementHandler::new(
|
||||
client.clone(),
|
||||
repository.clone(),
|
||||
HashMap::new(),
|
||||
));
|
||||
|
||||
let handler = charybdis_defectdojo::handlers::ProductHandler::new(
|
||||
client,
|
||||
|
||||
Reference in New Issue
Block a user