From 36f27e947da3f17ccfda29fdc95ce1eb8cf5f3af Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Tue, 22 Nov 2022 19:47:40 +0530 Subject: [PATCH] UI : Mask the JWT token in Metadata service (#8842) * Mask the Jwt token in Metadata service * minor fix * fix the icon alignment in Add Ingestion button * disable the test connection for metadata service OpenMetadata type * change the css name * fix unit test issue * Fix Auth Provider * Fix add ingestion dropdown icon alignment * Fix formatting * Do not encryt JWT auth mechanism with secrets manager Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Co-authored-by: ulixius9 Co-authored-by: Sachin Chaurasiya Co-authored-by: mohitdeuex Co-authored-by: Nahuel Verdugo Revigliono --- .../metadata/ingestion/ometa/auth_provider.py | 10 ++-- .../service/secrets/SecretsManager.java | 54 ++++++++++--------- .../client/openMetadataJWTClientConfig.json | 3 +- .../Ingestion/Ingestion.component.tsx | 8 +-- .../ServiceConfig/ConnectionConfigForm.tsx | 3 ++ .../ServiceConfig/ServiceConfig.tsx | 3 ++ .../ServiceConnectionDetails.component.tsx | 11 +++- .../common/FormBuilder/FormBuilder.tsx | 4 +- .../ui/src/constants/services.const.ts | 3 +- .../EditConnectionFormPage.component.tsx | 5 ++ .../src/main/resources/ui/src/styles/app.less | 14 +++-- 11 files changed, 79 insertions(+), 39 deletions(-) diff --git a/ingestion/src/metadata/ingestion/ometa/auth_provider.py b/ingestion/src/metadata/ingestion/ometa/auth_provider.py index 40249b56d32..b3dcf65b65c 100644 --- a/ingestion/src/metadata/ingestion/ometa/auth_provider.py +++ b/ingestion/src/metadata/ingestion/ometa/auth_provider.py @@ -440,11 +440,15 @@ class OpenMetadataAuthenticationProvider(AuthenticationProvider): def auth_token(self) -> None: if not self.jwt_token: - if os.path.isfile(self.security_config.jwtToken): - with open(self.security_config.jwtToken, "r", encoding="utf-8") as file: + if os.path.isfile(self.security_config.jwtToken.get_secret_value()): + with open( + self.security_config.jwtToken.get_secret_value(), + "r", + encoding="utf-8", + ) as file: self.jwt_token = file.read().rstrip() else: - self.jwt_token = self.security_config.jwtToken + self.jwt_token = self.security_config.jwtToken.get_secret_value() def get_access_token(self): self.auth_token() diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/secrets/SecretsManager.java b/openmetadata-service/src/main/java/org/openmetadata/service/secrets/SecretsManager.java index 483d4b29edd..d5d22ff4d8d 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/secrets/SecretsManager.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/secrets/SecretsManager.java @@ -20,11 +20,13 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Locale; +import java.util.Set; import lombok.Getter; import org.openmetadata.annotations.PasswordField; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline; import org.openmetadata.schema.entity.teams.AuthenticationMechanism; +import org.openmetadata.schema.security.client.OpenMetadataJWTClientConfig; import org.openmetadata.schema.security.secrets.SecretsManagerProvider; import org.openmetadata.service.exception.InvalidServiceConnectionException; import org.openmetadata.service.exception.SecretsManagerException; @@ -41,6 +43,8 @@ public abstract class SecretsManager { private Fernet fernet; + private static final Set> DO_NOT_ENCRYPT_CLASSES = Set.of(OpenMetadataJWTClientConfig.class); + protected SecretsManager(SecretsManagerProvider secretsManagerProvider, String clusterPrefix) { this.secretsManagerProvider = secretsManagerProvider; this.clusterPrefix = clusterPrefix; @@ -97,30 +101,32 @@ public abstract class SecretsManager { } private void encryptPasswordFields(Object toEncryptObject, String secretId) { - // for each get method - Arrays.stream(toEncryptObject.getClass().getMethods()) - .filter(this::isGetMethodOfObject) - .forEach( - method -> { - Object obj = getObjectFromMethod(method, toEncryptObject); - String fieldName = method.getName().replaceFirst("get", ""); - // if the object matches the package of openmetadata - if (obj != null && obj.getClass().getPackageName().startsWith("org.openmetadata")) { - // encryptPasswordFields - encryptPasswordFields(obj, buildSecretId(false, secretId, fieldName.toLowerCase(Locale.ROOT))); - // check if it has annotation - } else if (obj != null && method.getAnnotation(PasswordField.class) != null) { - // store value if proceed - String newFieldValue = storeValue(fieldName, (String) obj, secretId); - // get setMethod - Method toSet = getToSetMethod(toEncryptObject, obj, fieldName); - // set new value - setValueInMethod( - toEncryptObject, - Fernet.isTokenized(newFieldValue) ? newFieldValue : fernet.encrypt(newFieldValue), - toSet); - } - }); + if (!DO_NOT_ENCRYPT_CLASSES.contains(toEncryptObject.getClass())) { + // for each get method + Arrays.stream(toEncryptObject.getClass().getMethods()) + .filter(this::isGetMethodOfObject) + .forEach( + method -> { + Object obj = getObjectFromMethod(method, toEncryptObject); + String fieldName = method.getName().replaceFirst("get", ""); + // if the object matches the package of openmetadata + if (obj != null && obj.getClass().getPackageName().startsWith("org.openmetadata")) { + // encryptPasswordFields + encryptPasswordFields(obj, buildSecretId(false, secretId, fieldName.toLowerCase(Locale.ROOT))); + // check if it has annotation + } else if (obj != null && method.getAnnotation(PasswordField.class) != null) { + // store value if proceed + String newFieldValue = storeValue(fieldName, (String) obj, secretId); + // get setMethod + Method toSet = getToSetMethod(toEncryptObject, obj, fieldName); + // set new value + setValueInMethod( + toEncryptObject, + Fernet.isTokenized(newFieldValue) ? newFieldValue : fernet.encrypt(newFieldValue), + toSet); + } + }); + } } private void decryptPasswordFields(Object toDecryptObject) { diff --git a/openmetadata-spec/src/main/resources/json/schema/security/client/openMetadataJWTClientConfig.json b/openmetadata-spec/src/main/resources/json/schema/security/client/openMetadataJWTClientConfig.json index 5c9e51bae5a..5e9208c264e 100644 --- a/openmetadata-spec/src/main/resources/json/schema/security/client/openMetadataJWTClientConfig.json +++ b/openmetadata-spec/src/main/resources/json/schema/security/client/openMetadataJWTClientConfig.json @@ -8,7 +8,8 @@ "properties": { "jwtToken": { "description": "OpenMetadata generated JWT token.", - "type": "string" + "type": "string", + "format": "password" } }, "additionalProperties": false, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx index 4deaf1ee8b7..633468ed109 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx @@ -221,7 +221,7 @@ const Ingestion: React.FC = ({ const getAddIngestionButton = (type: PipelineType) => { return (