From 59aca1b12a8b6c71edc2f15e910f0950a012aa63 Mon Sep 17 00:00:00 2001
From: Jacob Champion <jacob.champion@enterprisedb.com>
Date: Wed, 1 Apr 2026 11:05:46 -0700
Subject: [PATCH v3.1 4/6] squash! Split PGOAUTHDEBUG=UNSAFE into multiple
 options

- Set specific debug flags in 001_server.pl.

- Add failing test to ensure ignored flags are actually ignored. Fix by
  inlining parse_debug_option().
---
 src/interfaces/libpq/fe-auth-oauth-debug.c    | 66 +++++--------------
 .../modules/oauth_validator/t/001_server.pl   | 22 ++++++-
 2 files changed, 38 insertions(+), 50 deletions(-)

diff --git a/src/interfaces/libpq/fe-auth-oauth-debug.c b/src/interfaces/libpq/fe-auth-oauth-debug.c
index c9a82b3f78e..8bf710ce46a 100644
--- a/src/interfaces/libpq/fe-auth-oauth-debug.c
+++ b/src/interfaces/libpq/fe-auth-oauth-debug.c
@@ -24,50 +24,6 @@
 
 #include "fe-auth-oauth.h"
 
-/*
- * Parse a single debug option from PGOAUTHDEBUG.
- * Returns true if the option is recognized, false otherwise.
- * Sets *is_unsafe to indicate if this option requires the UNSAFE: prefix.
- */
-static bool
-parse_debug_option(const char *option, uint32 *flags, bool *is_unsafe)
-{
-	*is_unsafe = false;
-
-	/* Unsafe options */
-	if (strcmp(option, "http") == 0)
-	{
-		*flags |= OAUTHDEBUG_UNSAFE_HTTP;
-		*is_unsafe = true;
-		return true;
-	}
-	else if (strcmp(option, "trace") == 0)
-	{
-		*flags |= OAUTHDEBUG_UNSAFE_TRACE;
-		*is_unsafe = true;
-		return true;
-	}
-	else if (strcmp(option, "dos-endpoint") == 0)
-	{
-		*flags |= OAUTHDEBUG_UNSAFE_DOS_ENDPOINT;
-		*is_unsafe = true;
-		return true;
-	}
-	/* Safe options */
-	else if (strcmp(option, "call-count") == 0)
-	{
-		*flags |= OAUTHDEBUG_CALL_COUNT;
-		return true;
-	}
-	else if (strcmp(option, "plugin-errors") == 0)
-	{
-		*flags |= OAUTHDEBUG_PLUGIN_ERRORS;
-		return true;
-	}
-
-	return false;
-}
-
 /*
  * Parses the PGOAUTHDEBUG environment variable and returns debug flags.
  *
@@ -109,22 +65,36 @@ oauth_get_debug_flags(void)
 	option = strtok_r(options_str, ",", &saveptr);
 	while (option != NULL)
 	{
-		bool		is_unsafe;
-
-		if (!parse_debug_option(option, &flags, &is_unsafe))
+		uint32		flag = 0;
+
+		if (strcmp(option, "http") == 0)
+			flag = OAUTHDEBUG_UNSAFE_HTTP;
+		else if (strcmp(option, "trace") == 0)
+			flag = OAUTHDEBUG_UNSAFE_TRACE;
+		else if (strcmp(option, "dos-endpoint") == 0)
+			flag = OAUTHDEBUG_UNSAFE_DOS_ENDPOINT;
+		else if (strcmp(option, "call-count") == 0)
+			flag = OAUTHDEBUG_CALL_COUNT;
+		else if (strcmp(option, "plugin-errors") == 0)
+			flag = OAUTHDEBUG_PLUGIN_ERRORS;
+		else
 		{
 			fprintf(stderr,
 					"WARNING: PGOAUTHDEBUG: unrecognized debug option \"%s\" (ignored)\n",
 					option);
 		}
-		else if (is_unsafe && !unsafe_prefix)
+
+		if (!unsafe_prefix && ((flag & OAUTHDEBUG_UNSAFE_MASK) != 0))
 		{
+			flag = 0;
+
 			fprintf(stderr,
 					"WARNING: PGOAUTHDEBUG: unsafe option \"%s\" requires UNSAFE: prefix (ignored)\n"
 					"Use: PGOAUTHDEBUG=UNSAFE:%s\n",
 					option, option);
 		}
 
+		flags |= flag;
 		option = strtok_r(NULL, ",", &saveptr);
 	}
 
diff --git a/src/test/modules/oauth_validator/t/001_server.pl b/src/test/modules/oauth_validator/t/001_server.pl
index c9c46e63539..3803dd08287 100644
--- a/src/test/modules/oauth_validator/t/001_server.pl
+++ b/src/test/modules/oauth_validator/t/001_server.pl
@@ -93,6 +93,21 @@ $node->connect_fails(
 	  qr@OAuth discovery URI "\Q$issuer\E/.well-known/openid-configuration" must use HTTPS@
 );
 
+{
+	# PGOAUTHDEBUG=http should have no effect (it needs an UNSAFE: marker).
+	local $ENV{PGOAUTHDEBUG} = "http";
+
+	$node->connect_fails(
+		"user=test dbname=postgres oauth_issuer=$issuer oauth_client_id=f02c6361-0635",
+		"HTTPS is required without debug mode (bad PGOAUTHDEBUG value)",
+		expected_stderr => qr[
+			^WARNING: .* \Qunsafe option "http" requires UNSAFE: prefix\E
+			.*
+			\QOAuth discovery URI "$issuer/.well-known/openid-configuration" must use HTTPS\E
+		]msx
+	);
+}
+
 # Switch to HTTPS.
 $issuer = "https://127.0.0.1:$port";
 
@@ -172,8 +187,11 @@ $node->connect_ok(
 	],
 	log_unlike => [qr/FATAL.*OAuth bearer authentication failed/]);
 
-# Enable PGOAUTHDEBUG for all remaining tests.
-$ENV{PGOAUTHDEBUG} = "UNSAFE";
+# Enable some debugging features for all remaining tests:
+# - trace, for detailed Curl logs on failure
+# - dos-endpoint, to speed up the three-way handshake
+# - call-count, for our later sanity check
+$ENV{PGOAUTHDEBUG} = "UNSAFE:trace,dos-endpoint,call-count";
 
 # The /alternate issuer uses slightly different parameters, along with an
 # OAuth-style discovery document.
-- 
2.34.1

