• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 Google LLC
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *    * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *    * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *
15  *    * Neither the name of Google LLC nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package com.google.auth.oauth2;
33 
34 import com.google.api.client.json.GenericJson;
35 import com.google.api.client.json.JsonObjectParser;
36 import com.google.auth.oauth2.IdentityPoolCredentialSource.CredentialFormatType;
37 import com.google.common.io.CharStreams;
38 import java.io.BufferedReader;
39 import java.io.File;
40 import java.io.FileInputStream;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.InputStreamReader;
44 import java.nio.charset.StandardCharsets;
45 import java.nio.file.Files;
46 import java.nio.file.LinkOption;
47 import java.nio.file.Paths;
48 
49 /**
50  * Internal provider for retrieving subject tokens for {@Link IdentityPoolCredentials} to exchange
51  * for GCP access tokens via a local file.
52  */
53 class FileIdentityPoolSubjectTokenSupplier implements IdentityPoolSubjectTokenSupplier {
54 
55   private final long serialVersionUID = 2475549052347431992L;
56 
57   private final IdentityPoolCredentialSource credentialSource;
58 
59   /**
60    * Constructor for FileIdentitySubjectTokenProvider
61    *
62    * @param credentialSource the credential source to use.
63    */
FileIdentityPoolSubjectTokenSupplier(IdentityPoolCredentialSource credentialSource)64   FileIdentityPoolSubjectTokenSupplier(IdentityPoolCredentialSource credentialSource) {
65     this.credentialSource = credentialSource;
66   }
67 
68   @Override
getSubjectToken(ExternalAccountSupplierContext context)69   public String getSubjectToken(ExternalAccountSupplierContext context) throws IOException {
70     String credentialFilePath = this.credentialSource.credentialLocation;
71     if (!Files.exists(Paths.get(credentialFilePath), LinkOption.NOFOLLOW_LINKS)) {
72       throw new IOException(
73           String.format(
74               "Invalid credential location. The file at %s does not exist.", credentialFilePath));
75     }
76     try {
77       return parseToken(new FileInputStream(new File(credentialFilePath)), this.credentialSource);
78     } catch (IOException e) {
79       throw new IOException(
80           "Error when attempting to read the subject token from the credential file.", e);
81     }
82   }
83 
parseToken(InputStream inputStream, IdentityPoolCredentialSource credentialSource)84   static String parseToken(InputStream inputStream, IdentityPoolCredentialSource credentialSource)
85       throws IOException {
86     if (credentialSource.credentialFormatType == CredentialFormatType.TEXT) {
87       BufferedReader reader =
88           new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
89       return CharStreams.toString(reader);
90     }
91 
92     JsonObjectParser parser = new JsonObjectParser(OAuth2Utils.JSON_FACTORY);
93     GenericJson fileContents =
94         parser.parseAndClose(inputStream, StandardCharsets.UTF_8, GenericJson.class);
95 
96     if (!fileContents.containsKey(credentialSource.subjectTokenFieldName)) {
97       throw new IOException("Invalid subject token field name. No subject token was found.");
98     }
99     return (String) fileContents.get(credentialSource.subjectTokenFieldName);
100   }
101 }
102