google/googleapis.dart

Auth: Support impersonate service account with gcloud cli

Open

#454 创建于 2022年9月30日

在 GitHub 查看
 (2 评论) (0 反应) (0 负责人)Dart (133 fork)github user discovery
enhancementhelp wantedpackage:googleapis_auth

仓库指标

Star
 (419 star)
PR 合并指标
 (PR 指标待抓取)

描述

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,
  );
}

贡献者指南