• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <glog/logging.h>
19 
20 namespace {
21 
22 std::chrono::steady_clock::duration REFRESH_WINDOW =
23     std::chrono::minutes(2);
24 std::string REFRESH_URL = "http://metadata.google.internal/computeMetadata/"
25     "v1/instance/service-accounts/default/token";
26 
27 }
28 
GceMetadataCredentialSource()29 GceMetadataCredentialSource::GceMetadataCredentialSource() {
30   latest_credential = "";
31   expiration = std::chrono::steady_clock::now();
32 }
33 
Credential()34 std::string GceMetadataCredentialSource::Credential() {
35   if (expiration - std::chrono::steady_clock::now() < REFRESH_WINDOW) {
36     RefreshCredential();
37   }
38   return latest_credential;
39 }
40 
RefreshCredential()41 void GceMetadataCredentialSource::RefreshCredential() {
42   Json::Value credential_json =
43       curl.DownloadToJson(REFRESH_URL, {"Metadata-Flavor: Google"});
44 
45   CHECK(!credential_json.isMember("error")) << "Error fetching credentials. " <<
46       "Response was " << credential_json;
47   bool has_access_token = credential_json.isMember("access_token");
48   bool has_expires_in = credential_json.isMember("expires_in");
49   if (!has_access_token || !has_expires_in) {
50     LOG(FATAL) << "GCE credential was missing access_token or expires_in. "
51         << "Full response was " << credential_json << "";
52   }
53 
54   expiration = std::chrono::steady_clock::now()
55       + std::chrono::seconds(credential_json["expires_in"].asInt());
56   latest_credential = credential_json["access_token"].asString();
57 }
58 
make()59 std::unique_ptr<CredentialSource> GceMetadataCredentialSource::make() {
60   return std::unique_ptr<CredentialSource>(new GceMetadataCredentialSource());
61 }
62 
FixedCredentialSource(const std::string & credential)63 FixedCredentialSource::FixedCredentialSource(const std::string& credential) {
64   this->credential = credential;
65 }
66 
Credential()67 std::string FixedCredentialSource::Credential() {
68   return credential;
69 }
70 
make(const std::string & credential)71 std::unique_ptr<CredentialSource> FixedCredentialSource::make(
72     const std::string& credential) {
73   return std::unique_ptr<CredentialSource>(new FixedCredentialSource(credential));
74 }
75