google/googleapis.dart

Auth: Support impersonate service account with gcloud cli

Open

#454 aberto em 30 de set. de 2022

Ver no GitHub
 (2 comments) (0 reactions) (0 assignees)Dart (133 forks)github user discovery
enhancementhelp wantedpackage:googleapis_auth

Métricas do repositório

Stars
 (419 stars)
Métricas de merge de PR
 (Métricas PR pendentes)

Description

Hi, It will be great if we can use impersonate service account with gcloud cli, so that it can test google service locally without downloading a service account.

currently clientViaApplicationDefaultCredentials will not use source_credentials when running this command

gcloud auth application-default login --impersonate-service-account=principal@example.iam.gserviceaccount.com

the parsing credentials here does not check for source_credentials. as a workaround I just added some code and work properly.

https://github.com/google/googleapis.dart/blob/02ed7aa02ce7fa304b7d5b40eb93b672f46cad63/googleapis_auth/lib/src/adc_utils.dart#L16

Future<AutoRefreshingAuthClient> fromApplicationsCredentialsFile(
  File file,
  String fileSource,
  List<String> scopes,
  Client baseClient,
) async {
  Object? credentials;
  try {
    credentials = json.decode(await file.readAsString());
  } on IOException {
    throw Exception(
      'Failed to read credentials file from $fileSource',
    );
  } on FormatException {
    throw Exception(
      'Failed to parse JSON from credentials file from $fileSource',
    );
  }

  if (credentials is Map && credentials['type'] == 'authorized_user') {
    final clientId = ClientId(
      credentials['client_id'] as String,
      credentials['client_secret'] as String?,
    );
    return AutoRefreshingClient(
      baseClient,
      clientId,
      await refreshCredentials(
        clientId,
        AccessCredentials(
          // Hack: Create empty credentials that have expired.
          AccessToken('Bearer', '', DateTime(0).toUtc()),
          credentials['refresh_token'] as String?,
          scopes,
        ),
        baseClient,
      ),
      quotaProject: credentials['quota_project_id'] as String?,
    );
  }

  if (credentials is Map && credentials['source_credentials']?['type'] == 'authorized_user') {
    final clientId = ClientId(
      credentials['source_credentials']['client_id'] as String,
      credentials['source_credentials']['client_secret'] as String?,
    );
    return AutoRefreshingClient(
      baseClient,
      clientId,
      await refreshCredentials(
        clientId,
        AccessCredentials(
          // Hack: Create empty credentials that have expired.
          AccessToken('Bearer', '', DateTime(0).toUtc()),
          credentials['source_credentials']['refresh_token'] as String?,
          scopes,
        ),
        baseClient,
      ),
      quotaProject: credentials['quota_project_id'] as String?,
    );
  }

  return await clientViaServiceAccount(
    ServiceAccountCredentials.fromJson(credentials),
    scopes,
    baseClient: baseClient,
  );
}

Guia do colaborador