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

feat(csharp/src/Drivers/Apache/Spark): Add OAuth access token auth type to Csharp Spark Driver #2579

Open
wants to merge 2 commits into
base: main
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
4 changes: 4 additions & 0 deletions csharp/src/Drivers/Apache/Spark/SparkAuthType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal enum SparkAuthType
UsernameOnly,
Basic,
Token,
OAuth,
Empty = int.MaxValue,
}

Expand All @@ -48,6 +49,9 @@ internal static bool TryParse(string? authType, out SparkAuthType authTypeValue)
case SparkAuthTypeConstants.Token:
authTypeValue = SparkAuthType.Token;
return true;
case SparkAuthTypeConstants.OAuth:
authTypeValue = SparkAuthType.OAuth;
return true;
default:
authTypeValue = default;
return false;
Expand Down
17 changes: 15 additions & 2 deletions csharp/src/Drivers/Apache/Spark/SparkHttpConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ protected override void ValidateAuthentication()
Properties.TryGetValue(AdbcOptions.Username, out string? username);
Properties.TryGetValue(AdbcOptions.Password, out string? password);
Properties.TryGetValue(SparkParameters.AuthType, out string? authType);
Properties.TryGetValue(SparkParameters.AccessToken, out string? access_token);
if (!SparkAuthTypeParser.TryParse(authType, out SparkAuthType authTypeValue))
{
throw new ArgumentOutOfRangeException(SparkParameters.AuthType, authType, $"Unsupported {SparkParameters.AuthType} value.");
Expand Down Expand Up @@ -83,6 +84,13 @@ protected override void ValidateAuthentication()
$"Parameters must include valid authentiation settings. Please provide either '{SparkParameters.Token}'; or '{AdbcOptions.Username}' and '{AdbcOptions.Password}'.",
nameof(Properties));
break;

case SparkAuthType.OAuth:
if (string.IsNullOrWhiteSpace(access_token))
throw new ArgumentException(
$"Parameter '{SparkParameters.AuthType}' is set to '{SparkAuthTypeConstants.OAuth}' but parameter '{SparkParameters.AccessToken}' is not set. Please provide a value for '{SparkParameters.AccessToken}'.",
nameof(Properties));
break;
default:
throw new ArgumentOutOfRangeException(SparkParameters.AuthType, authType, $"Unsupported {SparkParameters.AuthType} value.");
}
Expand Down Expand Up @@ -146,12 +154,13 @@ protected override TTransport CreateTransport()
throw new ArgumentOutOfRangeException(SparkParameters.AuthType, authType, $"Unsupported {SparkParameters.AuthType} value.");
}
Properties.TryGetValue(SparkParameters.Token, out string? token);
Properties.TryGetValue(SparkParameters.AccessToken, out string? access_token);
Properties.TryGetValue(AdbcOptions.Username, out string? username);
Properties.TryGetValue(AdbcOptions.Password, out string? password);
Properties.TryGetValue(AdbcOptions.Uri, out string? uri);

Uri baseAddress = GetBaseAddress(uri, hostName, path, port, SparkParameters.HostName);
AuthenticationHeaderValue? authenticationHeaderValue = GetAuthenticationHeaderValue(authTypeValue, token, username, password);
AuthenticationHeaderValue? authenticationHeaderValue = GetAuthenticationHeaderValue(authTypeValue, token, username, password, access_token);

HttpClientHandler httpClientHandler = NewHttpClientHandler();
HttpClient httpClient = new(httpClientHandler);
Expand Down Expand Up @@ -191,7 +200,7 @@ private HttpClientHandler NewHttpClientHandler()
return httpClientHandler;
}

private static AuthenticationHeaderValue? GetAuthenticationHeaderValue(SparkAuthType authType, string? token, string? username, string? password)
private static AuthenticationHeaderValue? GetAuthenticationHeaderValue(SparkAuthType authType, string? token, string? username, string? password, string? access_token)
{
if (!string.IsNullOrEmpty(token) && (authType == SparkAuthType.Empty || authType == SparkAuthType.Token))
{
Expand All @@ -205,6 +214,10 @@ private HttpClientHandler NewHttpClientHandler()
{
return new AuthenticationHeaderValue(BasicAuthenticationScheme, Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:")));
}
else if (!string.IsNullOrEmpty(access_token) && authType == SparkAuthType.OAuth)
{
return new AuthenticationHeaderValue(BearerAuthenticationScheme, access_token);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like mechanically, the only difference between token and oauth are the names and values of the connection parameters; an adbc.spark.auth_type of token with an adbc.spark.token property produces an identical outcome as an 'adbc.spark.auth_typeofoauthwith anadbc.spark.access_token` property. Is this expected?

}
else if (authType == SparkAuthType.None)
{
return null;
Expand Down
4 changes: 4 additions & 0 deletions csharp/src/Drivers/Apache/Spark/SparkParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public static class SparkParameters
public const string Port = "adbc.spark.port";
public const string Path = "adbc.spark.path";
public const string Token = "adbc.spark.token";

// access_token is required when authType is oauth
public const string AccessToken = "adbc.spark.access_token";
public const string AuthType = "adbc.spark.auth_type";
public const string Type = "adbc.spark.type";
public const string DataTypeConv = "adbc.spark.data_type_conv";
Expand All @@ -39,6 +42,7 @@ public static class SparkAuthTypeConstants
public const string UsernameOnly = "username_only";
public const string Basic = "basic";
public const string Token = "token";
public const string OAuth = "oauth";
}

public static class SparkServerTypeConstants
Expand Down
7 changes: 6 additions & 1 deletion csharp/test/Drivers/Apache/Spark/DriverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,24 @@ public override void CanDetectInvalidAuthentication()
Dictionary<string, string> parameters = GetDriverParameters(TestConfiguration);

bool hasToken = parameters.TryGetValue(SparkParameters.Token, out var token) && !string.IsNullOrEmpty(token);
bool hasAccessToken = parameters.TryGetValue(SparkParameters.Token, out var access_token) && !string.IsNullOrEmpty(access_token);
bool hasUsername = parameters.TryGetValue(AdbcOptions.Username, out var username) && !string.IsNullOrEmpty(username);
bool hasPassword = parameters.TryGetValue(AdbcOptions.Password, out var password) && !string.IsNullOrEmpty(password);
if (hasToken)
{
parameters[SparkParameters.Token] = "invalid-token";
}
else if (hasAccessToken)
{
parameters[SparkParameters.AccessToken] = "invalid-access-token";
}
else if (hasUsername && hasPassword)
{
parameters[AdbcOptions.Password] = "invalid-password";
}
else
{
Assert.Fail($"Unexpected configuration. Must provide '{SparkParameters.Token}' or '{AdbcOptions.Username}' and '{AdbcOptions.Password}'.");
Assert.Fail($"Unexpected configuration. Must provide '{SparkParameters.Token}' or '{SparkParameters.AccessToken}' or '{AdbcOptions.Username}' and '{AdbcOptions.Password}'.");
}

AdbcDatabase database = driver.Open(parameters);
Expand Down
3 changes: 3 additions & 0 deletions csharp/test/Drivers/Apache/Spark/SparkTestConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@ public class SparkTestConfiguration : ApacheTestConfiguration
[JsonPropertyName("token"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string Token { get; set; } = string.Empty;

[JsonPropertyName("access_token"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string AccessToken { get; set; } = string.Empty;

}
}
4 changes: 4 additions & 0 deletions csharp/test/Drivers/Apache/Spark/SparkTestEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public override Dictionary<string, string> GetDriverParameters(SparkTestConfigur
{
parameters.Add(SparkParameters.Token, testConfiguration.Token!);
}
if (!string.IsNullOrEmpty(testConfiguration.AccessToken))
{
parameters.Add(SparkParameters.AccessToken, testConfiguration.AccessToken);
}
if (!string.IsNullOrEmpty(testConfiguration.Username))
{
parameters.Add(AdbcOptions.Username, testConfiguration.Username!);
Expand Down
Loading