Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-1689931 Adding flag to skip token file permission verification #1959

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.snowflake.client.config;

import static net.snowflake.client.jdbc.SnowflakeUtil.convertSystemGetEnvToBooleanValue;
import static net.snowflake.client.jdbc.SnowflakeUtil.systemGetEnv;

import com.fasterxml.jackson.dataformat.toml.TomlMapper;
Expand Down Expand Up @@ -34,6 +35,52 @@ public class SFConnectionConfigParser {
"SNOWFLAKE_DEFAULT_CONNECTION_NAME";
public static final String DEFAULT = "default";
public static final String SNOWFLAKE_TOKEN_FILE_PATH = "/snowflake/session/token";
public static final String SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION =
"SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION";

public static ConnectionParameters buildConnectionParameters() throws SnowflakeSQLException {
String defaultConnectionName =
Optional.ofNullable(systemGetEnv(SNOWFLAKE_DEFAULT_CONNECTION_NAME_KEY)).orElse(DEFAULT);
Map<String, String> fileConnectionConfiguration =
loadDefaultConnectionConfiguration(defaultConnectionName);

if (fileConnectionConfiguration != null && !fileConnectionConfiguration.isEmpty()) {
Properties conectionProperties = new Properties();
conectionProperties.putAll(fileConnectionConfiguration);

String url = createUrl(fileConnectionConfiguration);
logger.debug("Url created using parameters from connection configuration file: {}", url);

if ("oauth".equals(fileConnectionConfiguration.get("authenticator"))
&& fileConnectionConfiguration.get("token") == null) {
Path path =
Paths.get(
Optional.ofNullable(fileConnectionConfiguration.get("token_file_path"))
.orElse(SNOWFLAKE_TOKEN_FILE_PATH));
logger.debug("Token used in connect is read from file: {}", path);
try {
boolean shouldSkipTokenFilePermissionsVerification =
convertSystemGetEnvToBooleanValue(SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION, false);
if (!shouldSkipTokenFilePermissionsVerification) {
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
verifyFilePermissionSecure(path);
} else {
logger.debug("Skip token file permissions verification");
}
String token = new String(Files.readAllBytes(path), Charset.defaultCharset());
if (!token.isEmpty()) {
putPropertyIfNotNull(conectionProperties, "token", token.trim());
} else {
logger.warn("The token has empty value");
}
} catch (Exception ex) {
throw new SnowflakeSQLException(ex, "There is a problem during reading token from file");
}
}
return new ConnectionParameters(url, conectionProperties);
} else {
return null;
}
}

private static Map<String, String> loadDefaultConnectionConfiguration(
String defaultConnectionName) throws SnowflakeSQLException {
Expand Down Expand Up @@ -88,44 +135,6 @@ private static void verifyFilePermissionSecure(Path configFilePath)
}
}

public static ConnectionParameters buildConnectionParameters() throws SnowflakeSQLException {
String defaultConnectionName =
Optional.ofNullable(systemGetEnv(SNOWFLAKE_DEFAULT_CONNECTION_NAME_KEY)).orElse(DEFAULT);
Map<String, String> fileConnectionConfiguration =
loadDefaultConnectionConfiguration(defaultConnectionName);

if (fileConnectionConfiguration != null && !fileConnectionConfiguration.isEmpty()) {
Properties conectionProperties = new Properties();
conectionProperties.putAll(fileConnectionConfiguration);

String url = createUrl(fileConnectionConfiguration);
logger.debug("Url created using parameters from connection configuration file: {}", url);

if ("oauth".equals(fileConnectionConfiguration.get("authenticator"))
&& fileConnectionConfiguration.get("token") == null) {
Path path =
Paths.get(
Optional.ofNullable(fileConnectionConfiguration.get("token_file_path"))
.orElse(SNOWFLAKE_TOKEN_FILE_PATH));
logger.debug("Token used in connect is read from file: {}", path);
try {
verifyFilePermissionSecure(path);
String token = new String(Files.readAllBytes(path), Charset.defaultCharset());
if (!token.isEmpty()) {
putPropertyIfNotNull(conectionProperties, "token", token.trim());
} else {
logger.warn("The token has empty value");
}
} catch (Exception ex) {
throw new SnowflakeSQLException(ex, "There is a problem during reading token from file");
}
}
return new ConnectionParameters(url, conectionProperties);
} else {
return null;
}
}

private static String createUrl(Map<String, String> fileConnectionConfiguration)
throws SnowflakeSQLException {
Optional<String> maybeAccount = Optional.ofNullable(fileConnectionConfiguration.get("account"));
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/net/snowflake/client/jdbc/SnowflakeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,22 @@ public static boolean convertSystemPropertyToBooleanValue(
}
return defaultValue;
}
/**
* Helper function to convert environment variable to boolean
*
* @param envVariableKey property name of the environment variable
* @param defaultValue default value used
* @return the value of the environment variable as boolean, else the default value
*/
@SnowflakeJdbcInternalApi
public static boolean convertSystemGetEnvToBooleanValue(
String envVariableKey, boolean defaultValue) {
String environmentVariableValue = systemGetEnv(envVariableKey);
if (environmentVariableValue != null) {
return Boolean.parseBoolean(environmentVariableValue);
}
return defaultValue;
}

@SnowflakeJdbcInternalApi
public static <T> T mapSFExceptionToSQLException(ThrowingCallable<T, SFException> action)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.snowflake.client.config;

import static net.snowflake.client.config.SFConnectionConfigParser.SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION;
import static net.snowflake.client.config.SFConnectionConfigParser.SNOWFLAKE_DEFAULT_CONNECTION_NAME_KEY;
import static net.snowflake.client.config.SFConnectionConfigParser.SNOWFLAKE_HOME_KEY;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -44,6 +45,7 @@ public void setUp() throws IOException {
public void close() throws IOException {
SnowflakeUtil.systemUnsetEnv(SNOWFLAKE_HOME_KEY);
SnowflakeUtil.systemUnsetEnv(SNOWFLAKE_DEFAULT_CONNECTION_NAME_KEY);
SnowflakeUtil.systemUnsetEnv(SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION);
Files.walk(tempPath).map(Path::toFile).forEach(File::delete);
Files.delete(tempPath);
}
Expand Down Expand Up @@ -103,6 +105,21 @@ public void testThrowErrorWhenWrongPermissionsForTokenFile() throws IOException
SnowflakeSQLException.class, () -> SFConnectionConfigParser.buildConnectionParameters());
}

@Test
public void testNoThrowErrorWhenWrongPermissionsForTokenFileButSkippingFlagIsEnabled()
throws SnowflakeSQLException, IOException {
SnowflakeUtil.systemSetEnv(SNOWFLAKE_HOME_KEY, tempPath.toString());
SnowflakeUtil.systemSetEnv(SNOWFLAKE_DEFAULT_CONNECTION_NAME_KEY, "default");
SnowflakeUtil.systemSetEnv(SKIP_TOKEN_FILE_PERMISSIONS_VERIFICATION, "true");
File tokenFile = new File(Paths.get(tempPath.toString(), "token").toUri());
prepareConnectionConfigurationTomlFile(
Collections.singletonMap("token_file_path", tokenFile.toString()), true, false);

ConnectionParameters data = SFConnectionConfigParser.buildConnectionParameters();
assertNotNull(data);
assertEquals(tokenFile.toString(), data.getParams().get("token_file_path"));
}

@Test
public void testLoadSFConnectionConfigWithHostConfigured()
throws SnowflakeSQLException, IOException {
Expand Down
Loading