From 71923eb63497c14d3f08a1508ce5f0f729584b51 Mon Sep 17 00:00:00 2001 From: F04C Date: Tue, 27 Jan 2026 10:13:15 +0800 Subject: [PATCH] add unresolved placeholders --- services/policy_evaluator.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/services/policy_evaluator.go b/services/policy_evaluator.go index a9684a3..3457deb 100644 --- a/services/policy_evaluator.go +++ b/services/policy_evaluator.go @@ -40,6 +40,18 @@ func resolveVariables(value string, ctx *models.AuthorizationContext) string { }) } +// hasUnresolvedPlaceholders checks if a string still contains placeholders that couldn't be resolved +func hasUnresolvedPlaceholders(value string) bool { + re := regexp.MustCompile(`\$\{[^}]+\}`) + return re.MatchString(value) +} + +// extractUnresolvedPlaceholders returns a list of unresolved placeholders +func extractUnresolvedPlaceholders(value string) []string { + re := regexp.MustCompile(`\$\{[^}]+\}`) + return re.FindAllString(value, -1) +} + // compare evaluates comparison operators between actual and expected values // Note: "=" and "!=" are case-sensitive, while IN/CONTAINS/STARTS_WITH/ENDS_WITH are case-insensitive func compare(actual, expected, operator string) bool { @@ -151,6 +163,20 @@ func evaluatePolicy(policyAttribute models.PolicyAttribute, ctx *models.Authoriz if !satisfied { fmt.Printf(" Result: ❌ FAILED\n\n") + + // Check if the failure is due to unresolved placeholders + if hasUnresolvedPlaceholders(expectedValue) { + unresolvedPlaceholders := extractUnresolvedPlaceholders(expectedValue) + return false, fmt.Sprintf( + "Policy failed: %s %s %s (actual: %s) - Missing required attributes: %v", + policyAttribute.AttributeName, + policyAttribute.Comparison, + expectedValue, + actualValue, + unresolvedPlaceholders, + ) + } + return false, fmt.Sprintf( "Policy failed: %s %s %s (actual: %s)", policyAttribute.AttributeName,