Skip to content
Draft
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
Expand Up @@ -72,7 +72,6 @@ StatusRecordOr<std::shared_ptr<Credentials>> CreateServiceCredentials(
"Service Account key file is empty or could not be read: " +
credentials_file_path};
}

return ::google::cloud::MakeServiceAccountCredentials(contents, options);
}

Expand Down Expand Up @@ -194,6 +193,7 @@ StatusRecordOr<AccessToken> GetOAuth2Token(
auto self_signed_jwt_disabled = GetEnv(kSelfSignedJwtEnvVar);
SetEnv(kSelfSignedJwtEnvVar, "true");
StatusOr<AccessToken> access_token = generator->GetToken();
std::cout << "Access Token: " << access_token->token << std::endl;
SetEnv(kSelfSignedJwtEnvVar, self_signed_jwt_disabled);
return StatusRecordOr<AccessToken>::ConvertFromStatusOr(access_token);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct Oauth {
std::string kms_key_name;
std::string psc;
TPC tpc;
bool request_google_drive_scope = false;
};

// Returns true if all required BYOID properties are set.
Expand Down
25 changes: 24 additions & 1 deletion google/cloud/odbc/bq_client_interface/odbc_bq_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,27 @@ StatusRecordOr<std::shared_ptr<ODBCBQClient>> ODBCBQClient::CreateBQClient(
options.set<google::cloud::UserAgentProductsOption>(
{"Google-Bigquery-ODBC/" + std::string(DRIVER_VERSION)});

if(oauth.request_google_drive_scope) {
options.set<google::cloud::ScopesOption>(
{"https://www.googleapis.com/auth/bigquery",
"https://www.googleapis.com/auth/drive.readonly"});
} else {
options.set<google::cloud::ScopesOption>(
{"https://www.googleapis.com/auth/bigquery"}
);
}
// if (!oauth.request_google_drive_scope) {
// std::unordered_multimap<std::string, std::string> custom_headers;

// // This tells Google's API Gateway to ignore full platform credential fallback
// // and strictly evaluate the request within the narrow perimeter of BigQuery.
// custom_headers.insert({"X-Goog-Allowed-Resources", "bigquery.googleapis.com"});

// // Alternatively, some Google endpoints accept context downscoping headers:
// custom_headers.insert({"X-Google-Target-Scopes", "https://www.googleapis.com/auth/bigquery"});

// options.set<google::cloud::CustomHeadersOption>(custom_headers);
// }
StatusRecordOr<std::shared_ptr<Credentials>> credentials =
CreateCredentials(oauth, options);
if (!credentials) {
Expand Down Expand Up @@ -231,7 +252,9 @@ StatusRecordOr<std::shared_ptr<ODBCBQClient>> ODBCBQClient::CreateBQClient(
if (!bigquery_endpoint.empty()) {
rest_options.set<google::cloud::EndpointOption>(bigquery_endpoint);
}

rest_options.set<google::cloud::ScopesOption>(
{"https://www.googleapis.com/auth/bigquery"}
);
DatasetClient dataset_client =
DatasetClient(MakeDatasetConnection(rest_options));
JobClient job_client = JobClient(MakeBigQueryJobConnection(rest_options));
Expand Down
4 changes: 4 additions & 0 deletions google/cloud/odbc/bq_driver/internal/odbc_conn_handle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ void ConnectionHandle::SetUp(Section& dsn_section,
!max_retries.empty() ? std::stoull(max_retries) : kDefaultMaxRetries;

dsn_.pem_file = dsn_section["TRUSTEDCERTS"];
std::string request_google_drive_scope =
dsn_section["REQUESTGOOGLEDRIVESCOPE"];
dsn_.request_google_drive_scope = (request_google_drive_scope == "1" ||
request_google_drive_scope == "true");
#ifdef _WIN32
auto it = dsn_section.find("USESYSTEMTRUSTSTORE");
if (it != dsn_section.end() && !it->second.empty()) {
Expand Down
1 change: 1 addition & 0 deletions google/cloud/odbc/bq_driver/internal/odbc_conn_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct Dsn {
bool sessions_enabled = false;
bool is_query_cache = true;
bool filter_tables_on_default_dataset = false;
bool request_google_drive_scope = false;
std::string session_location;
std::vector<ConnectionProperty> connection_properties;
std::uint32_t row_fetched_per_block = 100000;
Expand Down
1 change: 1 addition & 0 deletions google/cloud/odbc/bq_driver/odbc_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Authentication CreateAuth(Dsn const& dsn) {
auth.oauth.kms_key_name = dsn.kms_key_name;
auth.oauth.psc = dsn.psc;
auth.oauth.tpc.enable_tpc = dsn.enable_tpc;
auth.oauth.request_google_drive_scope = dsn.request_google_drive_scope;
auth.oauth.tpc.universe_domain = dsn.universe_domain;
return auth;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4366,4 +4366,53 @@ TEST(SQLMoreResults, ProcedureWithDescriptorAndQueryParams) {
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
}

TEST(StatementTest, VerifyGoogleDriveScope_Enabled) {
auto conn = std::make_shared<ODBCHandles>();
std::string conn_str = kDefaultConnectionString +";RequestGoogleDriveScope=0";

std::string table_name =
kDatasetWithTablePrefix + "ODBC_GOOGLE_DRIVE_SCOPE_TEST";
EXPECT_EQ(Connect(conn_str, conn), SQL_SUCCESS);
std::string create_qry =
"CREATE OR REPLACE EXTERNAL TABLE " + kDatasetWithTablePrefix +
"ODBC_GOOGLE_DRIVE_SCOPE_TEST "
"(Student_ID INT64, "
"Major_Category STRING, "
"Year_of_Study STRING, "
"Pre_Semester_GPA FLOAT64) "
"OPTIONS ("
"format = 'GOOGLE_SHEETS', "
"uris = "
"['https://docs.google.com/spreadsheets/d/"
"19sVLFBoApdycZInuci8Hf7s12rOHKKlsdS6RmKkJdr8'], "
"skip_leading_rows = 1, "
"sheet_range = 'ai_student_impact_dataset'"
");";
auto status =
SQLExecDirect(conn->hstmt, (SQLCHAR*)create_qry.c_str(), SQL_NTS);
CheckError(status, "SQLExecDirect", conn);
EXPECT_EQ(status, SQL_SUCCESS);
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);

// // verify table
EXPECT_EQ(Connect(conn_str, conn), SQL_SUCCESS);
std::string select_qry = "SELECT * FROM " + table_name + " LIMIT 5";
status = SQLExecDirect(conn->hstmt, (SQLCHAR*)select_qry.c_str(), SQL_NTS);
CheckError(status, "SQLExecDirect", conn);
EXPECT_EQ(status, SQL_SUCCESS);

status = SQLFetch(conn->hstmt);
CheckError(status, "SQLFetch", conn);
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);

// // Cleanup.
// EXPECT_EQ(Connect(conn_str, conn), SQL_SUCCESS);
// std::string drop_qry = "DROP EXTERNAL TABLE `" + table_name + "`";

// status = SQLExecDirect(conn->hstmt, (SQLCHAR*)drop_qry.c_str(), SQL_NTS);

// EXPECT_EQ(status, SQL_SUCCESS);
// EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
}

} // namespace google::cloud::odbc_tests
Loading