# # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # import pytest from airbyte_cdk.utils.airbyte_secrets_utils import 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} **** ****"