@@ -117,6 +117,17 @@ static Map<String, String> parseOAuthProperties(DataSource ds, String callerClas
117117 throw new IllegalArgumentException (OAUTH_TYPE_ERROR_MESSAGE );
118118 }
119119 oauthProperties .put (BigQueryJdbcUrlUtility .OAUTH_TYPE_PROPERTY_NAME , String .valueOf (authType ));
120+
121+ Integer reqGoogleDriveScope = ds .getRequestGoogleDriveScope ();
122+ if ( reqGoogleDriveScope != null ){
123+ Boolean reqGoogleDriveScopeBool = BigQueryJdbcUrlUtility .convertIntToBoolean (String .valueOf (reqGoogleDriveScope ), BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME );
124+ oauthProperties .put (
125+ BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ,
126+ String .valueOf (reqGoogleDriveScopeBool ));
127+ LOG .fine ("RequestGoogleDriveScope parsed." );
128+ }
129+
130+
120131 switch (authType ) {
121132 case GOOGLE_SERVICE_ACCOUNT :
122133 // For using a Google Service Account (OAuth Type 0)
@@ -144,11 +155,6 @@ static Map<String, String> parseOAuthProperties(DataSource ds, String callerClas
144155 BigQueryJdbcUrlUtility .OAUTH_CLIENT_ID_PROPERTY_NAME , ds .getOAuthClientId ());
145156 oauthProperties .put (
146157 BigQueryJdbcUrlUtility .OAUTH_CLIENT_SECRET_PROPERTY_NAME , ds .getOAuthClientSecret ());
147- int reqGoogleDriveScope = ds .getRequestGoogleDriveScope ();
148- oauthProperties .put (
149- BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ,
150- String .valueOf (reqGoogleDriveScope ));
151- LOG .fine ("RequestGoogleDriveScope parsed." );
152158 break ;
153159 case PRE_GENERATED_TOKEN :
154160 String refreshToken = ds .getOAuthRefreshToken ();
@@ -280,7 +286,7 @@ static GoogleCredentials getCredentials(
280286 break ;
281287 case APPLICATION_DEFAULT_CREDENTIALS :
282288 // This auth method doesn't support service account impersonation
283- return getApplicationDefaultCredentials (callerClassName );
289+ return getApplicationDefaultCredentials (authProperties , callerClassName );
284290 case EXTERNAL_ACCOUNT_AUTH :
285291 // This auth method doesn't support service account impersonation
286292 return getExternalAccountAuthCredentials (authProperties , callerClassName );
@@ -373,6 +379,13 @@ private static GoogleCredentials getGoogleServiceAccountCredentials(
373379 builder .setUniverseDomain (
374380 overrideProperties .get (BigQueryJdbcUrlUtility .UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME ));
375381 }
382+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))){
383+ builder .setScopes (
384+ Arrays .asList (
385+ "https://www.googleapis.com/auth/bigquery" ,
386+ "https://www.googleapis.com/auth/drive.readonly" ));
387+ LOG .fine ("Added Google Drive read-only scope to Service Account builder." );
388+ }
376389 } catch (URISyntaxException | IOException e ) {
377390 LOG .severe ("Validation failure for Service Account credentials." );
378391 throw new BigQueryJdbcRuntimeException (e );
@@ -388,28 +401,6 @@ static UserAuthorizer getUserAuthorizer(
388401 String callerClassName )
389402 throws URISyntaxException {
390403 LOG .finest ("++enter++\t " + callerClassName );
391- List <String > scopes = new ArrayList <>();
392- scopes .add ("https://www.googleapis.com/auth/bigquery" );
393-
394- // Add Google Drive scope conditionally
395- if (authProperties .containsKey (
396- BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME )) {
397- try {
398- int driveScopeValue =
399- Integer .parseInt (
400- authProperties .get (
401- BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ));
402- if (driveScopeValue == 1 ) {
403- scopes .add ("https://www.googleapis.com/auth/drive.readonly" );
404- LOG .fine ("Added Google Drive read-only scope. Caller: " + callerClassName );
405- }
406- } catch (NumberFormatException e ) {
407- LOG .severe (
408- "Invalid value for RequestGoogleDriveScope, defaulting to not request Drive scope."
409- + " Caller: "
410- + callerClassName );
411- }
412- }
413404
414405 List <String > responseTypes = new ArrayList <>();
415406 responseTypes .add ("code" );
@@ -421,13 +412,21 @@ static UserAuthorizer getUserAuthorizer(
421412 UserAuthorizer .Builder userAuthorizerBuilder =
422413 UserAuthorizer .newBuilder ()
423414 .setClientId (clientId )
424- .setScopes (scopes )
425415 .setCallbackUri (URI .create ("http://localhost:" + port ));
426416
427417 if (overrideProperties .containsKey (BigQueryJdbcUrlUtility .OAUTH2_TOKEN_URI_PROPERTY_NAME )) {
428418 userAuthorizerBuilder .setTokenServerUri (
429419 new URI (overrideProperties .get (BigQueryJdbcUrlUtility .OAUTH2_TOKEN_URI_PROPERTY_NAME )));
430420 }
421+ List <String > scopes = new ArrayList <>();
422+ scopes .add ("https://www.googleapis.com/auth/bigquery" );
423+
424+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
425+ scopes .add ("https://www.googleapis.com/auth/drive.readonly" );
426+ LOG .fine ("Added Google Drive read-only scope to User Account builder." );
427+ }
428+
429+ userAuthorizerBuilder .setScopes (scopes );
431430
432431 return userAuthorizerBuilder .build ();
433432 }
@@ -500,14 +499,27 @@ private static GoogleCredentials getPreGeneratedAccessTokenCredentials(
500499 builder .setUniverseDomain (
501500 overrideProperties .get (BigQueryJdbcUrlUtility .UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME ));
502501 }
502+
503503 LOG .info ("Connection established. Auth Method: Pre-generated Access Token." );
504- return builder
504+ GoogleCredentials credentials = builder
505505 .setAccessToken (
506506 AccessToken .newBuilder ()
507507 .setTokenValue (
508508 authProperties .get (BigQueryJdbcUrlUtility .OAUTH_ACCESS_TOKEN_PROPERTY_NAME ))
509509 .build ())
510510 .build ();
511+
512+
513+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
514+ credentials = credentials .createScoped (
515+ Arrays .asList (
516+ "https://www.googleapis.com/auth/bigquery" ,
517+ "https://www.googleapis.com/auth/drive.readonly"
518+ )
519+ );
520+ }
521+
522+ return credentials ;
511523 }
512524
513525 static GoogleCredentials getPreGeneratedTokensCredentials (
@@ -552,11 +564,22 @@ static UserCredentials getPreGeneratedRefreshTokenCredentials(
552564 userCredentialsBuilder .setUniverseDomain (
553565 overrideProperties .get (BigQueryJdbcUrlUtility .UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME ));
554566 }
567+
568+ UserCredentials userCredentials = userCredentialsBuilder .build ();
569+
570+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
571+ userCredentials = (UserCredentials ) userCredentials .createScoped (
572+ Arrays .asList (
573+ "https://www.googleapis.com/auth/bigquery" ,
574+ "https://www.googleapis.com/auth/drive.readonly"
575+ )
576+ );
577+ }
555578 LOG .info ("Connection established. Auth Method: Pre-generated Refresh Token." );
556- return userCredentialsBuilder . build () ;
579+ return userCredentials ;
557580 }
558581
559- private static GoogleCredentials getApplicationDefaultCredentials (String callerClassName ) {
582+ private static GoogleCredentials getApplicationDefaultCredentials (Map < String , String > authProperties , String callerClassName ) {
560583 LOG .finest ("++enter++\t " + callerClassName );
561584 try {
562585 GoogleCredentials credentials = GoogleCredentials .getApplicationDefault ();
@@ -571,6 +594,17 @@ private static GoogleCredentials getApplicationDefaultCredentials(String callerC
571594 LOG .info (
572595 "Connection established. Auth Method: Application Default Credentials, Principal: %s." ,
573596 principal );
597+
598+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
599+ credentials = credentials .createScoped (
600+ Arrays .asList (
601+ "https://www.googleapis.com/auth/bigquery" ,
602+ "https://www.googleapis.com/auth/drive.readonly"
603+ )
604+ );
605+ LOG .fine ("Added Google Drive read-only scope to ADC credentials." );
606+ }
607+
574608 return credentials ;
575609 } catch (IOException exception ) {
576610 // TODO throw exception
@@ -616,16 +650,29 @@ private static GoogleCredentials getExternalAccountAuthCredentials(
616650 }
617651 }
618652
653+ GoogleCredentials credentials ;
619654 if (credentialsPath != null ) {
620- return ExternalAccountCredentials .fromStream (
655+ credentials = ExternalAccountCredentials .fromStream (
621656 Files .newInputStream (Paths .get (credentialsPath )));
622657 } else if (jsonObject != null ) {
623- return ExternalAccountCredentials .fromStream (
658+ credentials = ExternalAccountCredentials .fromStream (
624659 new ByteArrayInputStream (jsonObject .toString ().getBytes ()));
625660 } else {
626661 throw new IllegalArgumentException (
627662 "Insufficient info provided for external authentication" );
628663 }
664+
665+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
666+ credentials = credentials .createScoped (
667+ Arrays .asList (
668+ "https://www.googleapis.com/auth/bigquery" ,
669+ "https://www.googleapis.com/auth/drive.readonly"
670+ )
671+ );
672+ LOG .fine ("Added Google Drive read-only scope to External Account credentials." );
673+ }
674+
675+ return credentials ;
629676 } catch (IOException e ) {
630677 throw new BigQueryJdbcRuntimeException (e );
631678 }
@@ -634,7 +681,7 @@ private static GoogleCredentials getExternalAccountAuthCredentials(
634681 // This function checks if connection string contains configuration for
635682 // credentials impersonation. If not, it returns regular credentials object.
636683 // If impersonated service account is provided, returns Credentials object
637- // accomodating this information.
684+ // accommodating this information.
638685 private static GoogleCredentials getServiceAccountImpersonatedCredentials (
639686 GoogleCredentials credentials , Map <String , String > authProperties ) {
640687
@@ -653,10 +700,18 @@ private static GoogleCredentials getServiceAccountImpersonatedCredentials(
653700
654701 // Scopes has a default value, so it should never be null
655702 List <String > impersonationScopes =
656- Arrays .asList (
657- authProperties
658- .get (BigQueryJdbcUrlUtility .OAUTH_SA_IMPERSONATION_SCOPES_PROPERTY_NAME )
659- .split ("," ));
703+ new java .util .ArrayList <>(
704+ Arrays .asList (
705+ authProperties
706+ .get (BigQueryJdbcUrlUtility .OAUTH_SA_IMPERSONATION_SCOPES_PROPERTY_NAME )
707+ .split ("," )));
708+
709+ if ("true" .equals (authProperties .get (BigQueryJdbcUrlUtility .REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME ))) {
710+ if (!impersonationScopes .contains ("https://www.googleapis.com/auth/drive.readonly" )) {
711+ impersonationScopes .add ("https://www.googleapis.com/auth/drive.readonly" );
712+ LOG .fine ("Added Google Drive read-only scope to impersonation scopes." );
713+ }
714+ }
660715
661716 // Token lifetime has a default value, so it should never be null
662717 String impersonationLifetime =
0 commit comments