1 // 2 // Copyright (C) 2019 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #include "credential_source.h" 17 18 #include <android-base/logging.h> 19 20 namespace cuttlefish { 21 namespace { 22 23 std::chrono::steady_clock::duration REFRESH_WINDOW = 24 std::chrono::minutes(2); 25 std::string REFRESH_URL = "http://metadata.google.internal/computeMetadata/" 26 "v1/instance/service-accounts/default/token"; 27 28 } // namespace 29 GceMetadataCredentialSource()30GceMetadataCredentialSource::GceMetadataCredentialSource() { 31 latest_credential = ""; 32 expiration = std::chrono::steady_clock::now(); 33 } 34 Credential()35std::string GceMetadataCredentialSource::Credential() { 36 if (expiration - std::chrono::steady_clock::now() < REFRESH_WINDOW) { 37 RefreshCredential(); 38 } 39 return latest_credential; 40 } 41 RefreshCredential()42void GceMetadataCredentialSource::RefreshCredential() { 43 Json::Value credential_json = 44 curl.DownloadToJson(REFRESH_URL, {"Metadata-Flavor: Google"}); 45 46 CHECK(!credential_json.isMember("error")) << "Error fetching credentials. " << 47 "Response was " << credential_json; 48 bool has_access_token = credential_json.isMember("access_token"); 49 bool has_expires_in = credential_json.isMember("expires_in"); 50 if (!has_access_token || !has_expires_in) { 51 LOG(FATAL) << "GCE credential was missing access_token or expires_in. " 52 << "Full response was " << credential_json << ""; 53 } 54 55 expiration = std::chrono::steady_clock::now() 56 + std::chrono::seconds(credential_json["expires_in"].asInt()); 57 latest_credential = credential_json["access_token"].asString(); 58 } 59 make()60std::unique_ptr<CredentialSource> GceMetadataCredentialSource::make() { 61 return std::unique_ptr<CredentialSource>(new GceMetadataCredentialSource()); 62 } 63 FixedCredentialSource(const std::string & credential)64FixedCredentialSource::FixedCredentialSource(const std::string& credential) { 65 this->credential = credential; 66 } 67 Credential()68std::string FixedCredentialSource::Credential() { 69 return credential; 70 } 71 make(const std::string & credential)72std::unique_ptr<CredentialSource> FixedCredentialSource::make( 73 const std::string& credential) { 74 return std::unique_ptr<CredentialSource>(new FixedCredentialSource(credential)); 75 } 76 77 } // namespace cuttlefish 78