mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-31 20:51:26 +00:00
Fix: Improve error messages (#11244)
This commit is contained in:
parent
33c429f67c
commit
a4af11fba4
@ -62,6 +62,10 @@ public abstract class SecretsManager {
|
||||
return encryptOrDecryptPasswordFields(
|
||||
newConnectionConfig, buildSecretId(true, serviceType.value(), connectionName), encrypt, true);
|
||||
} catch (Exception e) {
|
||||
String message = SecretsUtil.buildExceptionMessageConnection(e.getMessage(), connectionType, encrypt);
|
||||
if (message != null) {
|
||||
throw new InvalidServiceConnectionException(message);
|
||||
}
|
||||
throw InvalidServiceConnectionException.byMessage(
|
||||
connectionType, String.format("Failed to encrypt connection instance of %s", connectionType));
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openmetadata.service.secrets;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SecretsUtil {
|
||||
|
||||
/**
|
||||
* Returns an error message when it is related to an Unrecognized field
|
||||
*
|
||||
* @param message the message to be formatted if the Unrecognized field is between quotes
|
||||
* @param defaultMessage default message to be formatted if the Unrecognized field is not between quotes
|
||||
* @param exceptionMessage the exception message
|
||||
* @param type the type of error
|
||||
* @return null if the message does not contain 'Unrecognized field' in the exception message
|
||||
*/
|
||||
public static String buildExceptionMessageUnrecognizedField(
|
||||
String message, String defaultMessage, String exceptionMessage, String type) {
|
||||
if (exceptionMessage != null && exceptionMessage.contains("Unrecognized field")) {
|
||||
Pattern pattern = Pattern.compile("Unrecognized field \"(.*?)\"");
|
||||
Matcher matcher = pattern.matcher(exceptionMessage);
|
||||
if (matcher.find()) {
|
||||
String fieldValue = matcher.group(1);
|
||||
return String.format(message, type, fieldValue);
|
||||
}
|
||||
return String.format(defaultMessage, type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String buildExceptionMessageConnection(
|
||||
String exceptionMessage, String type, String firstAction, String secondAction, boolean isFirstAction) {
|
||||
return buildExceptionMessageUnrecognizedField(
|
||||
"Failed to "
|
||||
+ (isFirstAction ? firstAction : secondAction)
|
||||
+ " '%s' connection stored in DB due to an unrecognized field: '%s'",
|
||||
"Failed to "
|
||||
+ (isFirstAction ? firstAction : secondAction)
|
||||
+ " '%s' connection stored in DB due to malformed connection object.",
|
||||
exceptionMessage,
|
||||
type);
|
||||
}
|
||||
|
||||
public static String buildExceptionMessageConnection(String exceptionMessage, String type, boolean encrypt) {
|
||||
return buildExceptionMessageConnection(exceptionMessage, type, "encrypt", "decrypt", encrypt);
|
||||
}
|
||||
|
||||
public static String buildExceptionMessageConnectionMask(String exceptionMessage, String type, boolean mask) {
|
||||
return buildExceptionMessageConnection(exceptionMessage, type, "mask", "unmask", mask);
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipel
|
||||
import org.openmetadata.schema.entity.teams.AuthenticationMechanism;
|
||||
import org.openmetadata.service.exception.EntityMaskException;
|
||||
import org.openmetadata.service.fernet.Fernet;
|
||||
import org.openmetadata.service.secrets.SecretsUtil;
|
||||
import org.openmetadata.service.secrets.converter.ClassConverterFactory;
|
||||
import org.openmetadata.service.util.AuthenticationMechanismBuilder;
|
||||
import org.openmetadata.service.util.IngestionPipelineBuilder;
|
||||
@ -54,6 +55,10 @@ public class PasswordEntityMasker extends EntityMasker {
|
||||
maskPasswordFields(convertedConnectionConfig);
|
||||
return convertedConnectionConfig;
|
||||
} catch (Exception e) {
|
||||
String message = SecretsUtil.buildExceptionMessageConnectionMask(e.getMessage(), connectionType, true);
|
||||
if (message != null) {
|
||||
throw new EntityMaskException(message);
|
||||
}
|
||||
throw new EntityMaskException(String.format("Failed to mask connection instance of %s", connectionType));
|
||||
}
|
||||
}
|
||||
@ -109,6 +114,10 @@ public class PasswordEntityMasker extends EntityMasker {
|
||||
unmaskPasswordFields(toUnmaskConfig, NEW_KEY, passwordsMap);
|
||||
return toUnmaskConfig;
|
||||
} catch (Exception e) {
|
||||
String message = SecretsUtil.buildExceptionMessageConnectionMask(e.getMessage(), connectionType, false);
|
||||
if (message != null) {
|
||||
throw new EntityMaskException(message);
|
||||
}
|
||||
throw new EntityMaskException(String.format("Failed to unmask connection instance of %s", connectionType));
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ package org.openmetadata.service.secrets;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@ -41,6 +42,7 @@ import org.openmetadata.schema.security.secrets.SecretsManagerProvider;
|
||||
import org.openmetadata.schema.services.connections.database.MysqlConnection;
|
||||
import org.openmetadata.schema.services.connections.metadata.OpenMetadataConnection;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.exception.InvalidServiceConnectionException;
|
||||
import org.openmetadata.service.fernet.Fernet;
|
||||
import org.openmetadata.service.util.JsonUtils;
|
||||
|
||||
@ -105,6 +107,34 @@ public abstract class ExternalSecretsManagerTest {
|
||||
testEncryptWorkflowObject(ENCRYPT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceptionConnection() {
|
||||
CreateDatabaseService.DatabaseServiceType databaseServiceType = CreateDatabaseService.DatabaseServiceType.Mysql;
|
||||
String connectionName = "test";
|
||||
Map<String, String> mysqlConnection = Map.of("password", "openmetadata-test", "username1", "openmetadata-test");
|
||||
|
||||
InvalidServiceConnectionException thrown =
|
||||
Assertions.assertThrows(
|
||||
InvalidServiceConnectionException.class,
|
||||
() ->
|
||||
secretsManager.encryptOrDecryptServiceConnectionConfig(
|
||||
mysqlConnection, databaseServiceType.value(), connectionName, ServiceType.DATABASE, true));
|
||||
|
||||
Assertions.assertEquals(
|
||||
"Failed to encrypt 'Mysql' connection stored in DB due to an unrecognized field: 'username1'",
|
||||
thrown.getMessage());
|
||||
thrown =
|
||||
Assertions.assertThrows(
|
||||
InvalidServiceConnectionException.class,
|
||||
() ->
|
||||
secretsManager.encryptOrDecryptServiceConnectionConfig(
|
||||
mysqlConnection, databaseServiceType.value(), connectionName, ServiceType.DATABASE, false));
|
||||
|
||||
Assertions.assertEquals(
|
||||
"Failed to decrypt 'Mysql' connection stored in DB due to an unrecognized field: 'username1'",
|
||||
thrown.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReturnsExpectedSecretManagerProvider() {
|
||||
assertEquals(expectedSecretManagerProvider(), secretsManager.getSecretsManagerProvider());
|
||||
|
@ -1,5 +1,12 @@
|
||||
package org.openmetadata.service.secrets.masker;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openmetadata.schema.entity.services.ServiceType;
|
||||
import org.openmetadata.schema.services.connections.database.MysqlConnection;
|
||||
import org.openmetadata.service.exception.EntityMaskException;
|
||||
|
||||
public class PasswordEntityMaskerTest extends TestEntityMasker {
|
||||
public PasswordEntityMaskerTest() {
|
||||
CONFIG.setMaskPasswordsAPI(true);
|
||||
@ -9,4 +16,35 @@ public class PasswordEntityMaskerTest extends TestEntityMasker {
|
||||
protected String getMaskedPassword() {
|
||||
return PasswordEntityMasker.PASSWORD_MASK;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceptionConnection() {
|
||||
Map<String, String> mysqlConnectionObject =
|
||||
Map.of("password", "openmetadata-test", "username1", "openmetadata-test");
|
||||
|
||||
EntityMaskException thrown =
|
||||
Assertions.assertThrows(
|
||||
EntityMaskException.class,
|
||||
() -> {
|
||||
EntityMaskerFactory.createEntityMasker(CONFIG)
|
||||
.maskServiceConnectionConfig(mysqlConnectionObject, "Mysql", ServiceType.DATABASE);
|
||||
});
|
||||
|
||||
Assertions.assertEquals(
|
||||
"Failed to mask 'Mysql' connection stored in DB due to an unrecognized field: 'username1'",
|
||||
thrown.getMessage());
|
||||
|
||||
thrown =
|
||||
Assertions.assertThrows(
|
||||
EntityMaskException.class,
|
||||
() -> {
|
||||
EntityMaskerFactory.createEntityMasker(CONFIG)
|
||||
.unmaskServiceConnectionConfig(
|
||||
mysqlConnectionObject, new MysqlConnection(), "Mysql", ServiceType.DATABASE);
|
||||
});
|
||||
|
||||
Assertions.assertEquals(
|
||||
"Failed to unmask 'Mysql' connection stored in DB due to an unrecognized field: 'username1'",
|
||||
thrown.getMessage());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user