blob: 9c96515d2a73e712bf8a13b9986b95d51e2af6c7 [file] [log] [blame]
// Copyright 2022 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'dart:io';
import 'package:appengine/appengine.dart';
import 'package:googleapis/secretmanager/v1.dart';
import 'config.dart';
/// Access secrets for Google Cloud projects.
///
/// See also:
/// * https://cloud.google.com/secret-manager/docs
abstract class SecretManager {
const SecretManager();
Future<String> get(String key);
void put(String key, [String? value]);
}
class CloudSecretManager implements SecretManager {
CloudSecretManager();
final String projectId =
Platform.environment['APPLICATION_ID'] ?? Config.flutterGcpProjectId;
@override
Future<String> get(String key, {String? fields}) async {
final api = SecretManagerApi(authClientService);
final payload =
(await api.projects.secrets.versions.access(
'projects/$projectId/secrets/$key/versions/latest',
$fields: fields,
)).payload;
if (payload?.data == null) {
throw SecretManagerException(
'Failed to find secret for $key with \$fields=$fields',
);
}
return String.fromCharCodes(base64Decode(payload!.data!));
}
@override
void put(String key, [String? value]) =>
throw UnimplementedError('put is only supported for local runs');
}
/// Local instance of [SecretManager] for use in testing.
class LocalSecretManager implements SecretManager {
final Map<String, String?> _secrets = <String, String>{};
@override
Future<String> get(String key, {String? fields}) async {
if (_secrets.containsKey(key)) {
return _secrets[key]!;
} else if (Platform.environment.containsKey(key)) {
return Platform.environment[key]!;
}
throw Exception(
'Failed to find $key in environment. Try adding it to the environment variables',
);
}
@override
void put(String key, [String? value]) {
_secrets[key] = value;
}
}
class SecretManagerException implements Exception {
SecretManagerException([this.message]);
final String? message;
@override
String toString() => 'SecretManagerException: $message';
}