1
0
mirror of synced 2025-12-26 14:02:10 -05:00
Files
airbyte/airbyte-cdk/python/unit_tests/utils/test_secret_utils.py
2024-02-14 22:25:18 -08:00

136 lines
5.1 KiB
Python

#
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
#
import pytest
from airbyte_cdk.utils.airbyte_secrets_utils import add_to_secrets, filter_secrets, get_secret_paths, get_secrets, update_secrets
SECRET_STRING_KEY = "secret_key1"
SECRET_STRING_VALUE = "secret_value"
SECRET_STRING_2_KEY = "secret_key2"
SECRET_STRING_2_VALUE = "second_secret_val"
SECRET_INT_KEY = "secret_int"
SECRET_INT_VALUE = 1337
NOT_SECRET_KEY = "not_a_secret"
NOT_SECRET_VALUE = "unimportant value"
flat_spec_with_secret = {"properties": {SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}}}
flat_config_with_secret = {SECRET_STRING_KEY: SECRET_STRING_VALUE, NOT_SECRET_KEY: NOT_SECRET_VALUE}
flat_spec_with_secret_int = {
"properties": {SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}}
}
flat_config_with_secret_int = {SECRET_INT_KEY: SECRET_INT_VALUE, NOT_SECRET_KEY: NOT_SECRET_VALUE}
flat_spec_without_secrets = {"properties": {NOT_SECRET_KEY: {"type": "string"}}}
flat_config_without_secrets = {NOT_SECRET_KEY: NOT_SECRET_VALUE}
spec_with_oneof_secrets = {
"properties": {
SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True},
NOT_SECRET_KEY: {"type": "string"},
"credentials": {
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {SECRET_STRING_2_KEY: {"type": "string", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}},
},
{
"type": "object",
"properties": {SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}},
},
],
},
}
}
config_with_oneof_secrets_1 = {
SECRET_STRING_KEY: SECRET_STRING_VALUE,
NOT_SECRET_KEY: NOT_SECRET_VALUE,
"credentials": {SECRET_STRING_2_KEY: SECRET_STRING_2_VALUE},
}
config_with_oneof_secrets_2 = {
SECRET_STRING_KEY: SECRET_STRING_VALUE,
NOT_SECRET_KEY: NOT_SECRET_VALUE,
"credentials": {SECRET_INT_KEY: SECRET_INT_VALUE},
}
spec_with_nested_secrets = {
"properties": {
SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True},
NOT_SECRET_KEY: {"type": "string"},
"credentials": {
"type": "object",
"properties": {
SECRET_STRING_2_KEY: {"type": "string", "airbyte_secret": True},
NOT_SECRET_KEY: {"type": "string"},
SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True},
},
},
}
}
config_with_nested_secrets = {
SECRET_STRING_KEY: SECRET_STRING_VALUE,
NOT_SECRET_KEY: NOT_SECRET_VALUE,
"credentials": {SECRET_STRING_2_KEY: SECRET_STRING_2_VALUE, SECRET_INT_KEY: SECRET_INT_VALUE},
}
@pytest.mark.parametrize(
["spec", "expected"],
[
(flat_spec_with_secret, [[SECRET_STRING_KEY]]),
(flat_spec_without_secrets, []),
(flat_spec_with_secret_int, [[SECRET_INT_KEY]]),
(spec_with_oneof_secrets, [[SECRET_STRING_KEY], ["credentials", SECRET_STRING_2_KEY], ["credentials", SECRET_INT_KEY]]),
(spec_with_nested_secrets, [[SECRET_STRING_KEY], ["credentials", SECRET_STRING_2_KEY], ["credentials", SECRET_INT_KEY]]),
],
)
def test_get_secret_paths(spec, expected):
assert get_secret_paths(spec) == expected, f"Expected {spec} to yield secret paths {expected}"
@pytest.mark.parametrize(
["spec", "config", "expected"],
[
(flat_spec_with_secret, flat_config_with_secret, [SECRET_STRING_VALUE]),
(flat_spec_without_secrets, flat_config_without_secrets, []),
(flat_spec_with_secret_int, flat_config_with_secret_int, [SECRET_INT_VALUE]),
(spec_with_oneof_secrets, config_with_oneof_secrets_1, [SECRET_STRING_VALUE, SECRET_STRING_2_VALUE]),
(spec_with_oneof_secrets, config_with_oneof_secrets_2, [SECRET_STRING_VALUE, SECRET_INT_VALUE]),
(spec_with_nested_secrets, config_with_nested_secrets, [SECRET_STRING_VALUE, SECRET_STRING_2_VALUE, SECRET_INT_VALUE]),
],
)
def test_get_secrets(spec, config, expected):
assert get_secrets(spec, config) == expected, f"Expected the spec {spec} and config {config} to produce {expected}"
def test_secret_filtering():
sensitive_str = f"{SECRET_STRING_VALUE} {NOT_SECRET_VALUE} {SECRET_STRING_VALUE} {SECRET_STRING_2_VALUE}"
update_secrets([])
filtered = filter_secrets(sensitive_str)
assert filtered == sensitive_str
# the empty secret should not affect the result
update_secrets([""])
filtered = filter_secrets(sensitive_str)
assert filtered == sensitive_str
update_secrets([SECRET_STRING_VALUE, SECRET_STRING_2_VALUE])
filtered = filter_secrets(sensitive_str)
assert filtered == f"**** {NOT_SECRET_VALUE} **** ****"
def test_secrets_added_are_filtered():
ADDED_SECRET = "only_a_secret_if_added"
sensitive_str = f"{ADDED_SECRET} {NOT_SECRET_VALUE}"
filtered = filter_secrets(sensitive_str)
assert filtered == sensitive_str
add_to_secrets(ADDED_SECRET)
filtered = filter_secrets(sensitive_str)
assert filtered == f"**** {NOT_SECRET_VALUE}"