blob: b1b70f4cf94e88bf7f4d780bb30566d3961cba3d [file] [log] [blame] [edit]
//
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "credential_source.h"
#include <android-base/logging.h>
namespace cuttlefish {
namespace {
std::chrono::steady_clock::duration REFRESH_WINDOW =
std::chrono::minutes(2);
std::string REFRESH_URL = "http://metadata.google.internal/computeMetadata/"
"v1/instance/service-accounts/default/token";
} // namespace
GceMetadataCredentialSource::GceMetadataCredentialSource(CurlWrapper& curl)
: curl(curl) {
latest_credential = "";
expiration = std::chrono::steady_clock::now();
}
std::string GceMetadataCredentialSource::Credential() {
if (expiration - std::chrono::steady_clock::now() < REFRESH_WINDOW) {
RefreshCredential();
}
return latest_credential;
}
void GceMetadataCredentialSource::RefreshCredential() {
auto curl_response =
curl.DownloadToJson(REFRESH_URL, {"Metadata-Flavor: Google"});
const auto& json = curl_response.data;
if (!curl_response.HttpSuccess()) {
LOG(FATAL) << "Error fetching credentials. The server response was \""
<< json << "\", and code was " << curl_response.http_code;
}
CHECK(!json.isMember("error"))
<< "Response had \"error\" but had http success status. Received \""
<< json << "\"";
bool has_access_token = json.isMember("access_token");
bool has_expires_in = json.isMember("expires_in");
if (!has_access_token || !has_expires_in) {
LOG(FATAL) << "GCE credential was missing access_token or expires_in. "
<< "Full response was " << json << "";
}
expiration = std::chrono::steady_clock::now() +
std::chrono::seconds(json["expires_in"].asInt());
latest_credential = json["access_token"].asString();
}
std::unique_ptr<CredentialSource> GceMetadataCredentialSource::make(
CurlWrapper& curl) {
return std::unique_ptr<CredentialSource>(
new GceMetadataCredentialSource(curl));
}
FixedCredentialSource::FixedCredentialSource(const std::string& credential) {
this->credential = credential;
}
std::string FixedCredentialSource::Credential() {
return credential;
}
std::unique_ptr<CredentialSource> FixedCredentialSource::make(
const std::string& credential) {
return std::unique_ptr<CredentialSource>(new FixedCredentialSource(credential));
}
} // namespace cuttlefish