From a691720778cce3cd728a4accd2dd5b57eaa240bd Mon Sep 17 00:00:00 2001 From: Gengliang Wang Date: Mon, 31 May 2021 18:32:10 +0800 Subject: [PATCH] fix --- .../org/apache/spark/sql/internal/SQLConf.scala | 9 ++++++++- .../spark/sql/execution/command/SetCommand.scala | 6 ++++-- .../scala/org/apache/spark/sql/SQLQuerySuite.scala | 13 +++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala index 3dfe4dc8bee50..e368ee1d532d7 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala @@ -4051,11 +4051,18 @@ class SQLConf extends Serializable with Logging { * Redacts the given option map according to the description of SQL_OPTIONS_REDACTION_PATTERN. */ def redactOptions[K, V](options: Map[K, V]): Map[K, V] = { + redactOptions(options.toSeq).toMap + } + + /** + * Redacts the given option map according to the description of SQL_OPTIONS_REDACTION_PATTERN. + */ + def redactOptions[K, V](options: Seq[(K, V)]): Seq[(K, V)] = { val regexes = Seq( getConf(SQL_OPTIONS_REDACTION_PATTERN), SECRET_REDACTION_PATTERN.readFrom(reader)) - regexes.foldLeft(options.toSeq) { case (opts, r) => Utils.redact(Some(r), opts) }.toMap + regexes.foldLeft(options) { case (opts, r) => Utils.redact(Some(r), opts) } } /** diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/SetCommand.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/SetCommand.scala index c32d1d74c71f1..6f35c05016b1d 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/SetCommand.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/SetCommand.scala @@ -107,7 +107,8 @@ case class SetCommand(kv: Option[(String, Option[String])]) // Queries all key-value pairs that are set in the SQLConf of the sparkSession. case None => val runFunc = (sparkSession: SparkSession) => { - sparkSession.conf.getAll.toSeq.sorted.map { case (k, v) => Row(k, v) } + val redactedConf = SQLConf.get.redactOptions(sparkSession.conf.getAll) + redactedConf.toSeq.sorted.map { case (k, v) => Row(k, v) } } (keyValueOutput, runFunc) @@ -162,7 +163,8 @@ case class SetCommand(kv: Option[(String, Option[String])]) // very likely to change them based the default value they see. sparkSession.sharedState.hadoopConf.get(key, "") } - Seq(Row(key, value)) + val (_, redactedValue) = SQLConf.get.redactOptions(Seq((key, value))).head + Seq(Row(key, redactedValue)) } (keyValueOutput, runFunc) } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala index 26af0b9f81127..26919baecf711 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala @@ -1084,6 +1084,19 @@ class SQLQuerySuite extends QueryTest with SharedSparkSession with AdaptiveSpark checkAnswer(sql("SET io.file.buffer.size"), Row("io.file.buffer.size", "65536")) } + test("Set command should redact sensitive data") { + val key1 = "test.password" + val value1 = "test.value1" + val key2 = "test.token" + val value2 = "test.value2" + withSQLConf (key1 -> value1, key2 -> value2) { + checkAnswer(sql(s"SET $key1"), Row(key1, "*********(redacted)")) + checkAnswer(sql(s"SET $key2"), Row(key2, "*********(redacted)")) + val allValues = sql("SET").collect().map(_.getString(1)) + assert(!allValues.exists(v => v.contains(value1) || v.contains(value2))) + } + } + test("apply schema") { withTempView("applySchema1", "applySchema2", "applySchema3") { val schema1 = StructType(