1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package credsfile
16
17 import (
18 "encoding/json"
19 "os"
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 )
24
25 func TestParseServiceAccount(t *testing.T) {
26 b, err := os.ReadFile("../testdata/sa.json")
27 if err != nil {
28 t.Fatal(err)
29 }
30 got, err := ParseServiceAccount(b)
31 if err != nil {
32 t.Fatal(err)
33 }
34 want := &ServiceAccountFile{
35 Type: "service_account",
36 ProjectID: "fake_project",
37 PrivateKeyID: "abcdef1234567890",
38 PrivateKey: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALX0PQoe1igW12ikv1bN/r9lN749y2ijmbc/mFHPyS3hNTyOCjDvBbXYbDhQJzWVUikh4mvGBA07qTj79Xc3yBDfKP2IeyYQIFe0t0zkd7R9Zdn98Y2rIQC47aAbDfubtkU1U72t4zL11kHvoa0/RuFZjncvlr42X7be7lYh4p3NAgMBAAECgYASk5wDw4Az2ZkmeuN6Fk/y9H+Lcb2pskJIXjrL533vrDWGOC48LrsThMQPv8cxBky8HFSEklPpkfTF95tpD43iVwJRB/GrCtGTw65IfJ4/tI09h6zGc4yqvIo1cHX/LQ+SxKLGyir/dQM925rGt/VojxY5ryJR7GLbCzxPnJm/oQJBANwOCO6D2hy1LQYJhXh7O+RLtA/tSnT1xyMQsGT+uUCMiKS2bSKx2wxo9k7h3OegNJIu1q6nZ6AbxDK8H3+d0dUCQQDTrPSXagBxzp8PecbaCHjzNRSQE2in81qYnrAFNB4o3DpHyMMY6s5ALLeHKscEWnqP8Ur6X4PvzZecCWU9BKAZAkAutLPknAuxSCsUOvUfS1i87ex77Ot+w6POp34pEX+UWb+u5iFn2cQacDTHLV1LtE80L8jVLSbrbrlH43H0DjU5AkEAgidhycxS86dxpEljnOMCw8CKoUBd5I880IUahEiUltk7OLJYS/Ts1wbn3kPOVX3wyJs8WBDtBkFrDHW2ezth2QJADj3e1YhMVdjJW5jqwlD/VNddGjgzyunmiZg0uOXsHXbytYmsA545S8KRQFaJKFXYYFo2kOjqOiC1T2cAzMDjCQ==\n-----END PRIVATE KEY-----\n",
39 ClientEmail: "gopher@fake_project.iam.gserviceaccount.com",
40 ClientID: "gopher",
41 AuthURL: "https://accounts.google.com/o/oauth2/auth",
42 TokenURL: "https://oauth2.googleapis.com/token",
43 }
44 if diff := cmp.Diff(want, got); diff != "" {
45 t.Errorf("(-want +got):\n%s", diff)
46 }
47
48 }
49
50 func TestParseImpersonatedServiceAccount(t *testing.T) {
51 b, err := os.ReadFile("../testdata/imp.json")
52 if err != nil {
53 t.Fatal(err)
54 }
55 got, err := ParseImpersonatedServiceAccount(b)
56 if err != nil {
57 t.Fatal(err)
58 }
59 want := &ImpersonatedServiceAccountFile{
60 Type: "impersonated_service_account",
61 ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa3@developer.gserviceaccount.com:generateAccessToken",
62 Delegates: []string{
63 "sa1@developer.gserviceaccount.com",
64 "sa2@developer.gserviceaccount.com",
65 },
66 CredSource: json.RawMessage(`{
67 "type": "service_account",
68 "project_id": "fake_project",
69 "private_key_id": "89asd789789uo473454c47543",
70 "private_key": "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALX0PQoe1igW12ikv1bN/r9lN749y2ijmbc/mFHPyS3hNTyOCjDvBbXYbDhQJzWVUikh4mvGBA07qTj79Xc3yBDfKP2IeyYQIFe0t0zkd7R9Zdn98Y2rIQC47aAbDfubtkU1U72t4zL11kHvoa0/RuFZjncvlr42X7be7lYh4p3NAgMBAAECgYASk5wDw4Az2ZkmeuN6Fk/y9H+Lcb2pskJIXjrL533vrDWGOC48LrsThMQPv8cxBky8HFSEklPpkfTF95tpD43iVwJRB/GrCtGTw65IfJ4/tI09h6zGc4yqvIo1cHX/LQ+SxKLGyir/dQM925rGt/VojxY5ryJR7GLbCzxPnJm/oQJBANwOCO6D2hy1LQYJhXh7O+RLtA/tSnT1xyMQsGT+uUCMiKS2bSKx2wxo9k7h3OegNJIu1q6nZ6AbxDK8H3+d0dUCQQDTrPSXagBxzp8PecbaCHjzNRSQE2in81qYnrAFNB4o3DpHyMMY6s5ALLeHKscEWnqP8Ur6X4PvzZecCWU9BKAZAkAutLPknAuxSCsUOvUfS1i87ex77Ot+w6POp34pEX+UWb+u5iFn2cQacDTHLV1LtE80L8jVLSbrbrlH43H0DjU5AkEAgidhycxS86dxpEljnOMCw8CKoUBd5I880IUahEiUltk7OLJYS/Ts1wbn3kPOVX3wyJs8WBDtBkFrDHW2ezth2QJADj3e1YhMVdjJW5jqwlD/VNddGjgzyunmiZg0uOXsHXbytYmsA545S8KRQFaJKFXYYFo2kOjqOiC1T2cAzMDjCQ==\n-----END PRIVATE KEY-----\n",
71 "client_email": "sa@fake_project.iam.gserviceaccount.com",
72 "client_id": "gopher",
73 "auth_uri": "https://accounts.google.com/o/oauth2/auth",
74 "token_uri": "https://oauth2.googleapis.com/token"
75 }`),
76 }
77 if diff := cmp.Diff(want, got); diff != "" {
78 t.Errorf("(-want +got):\n%s", diff)
79 }
80
81 }
82
83 func TestParseGDCHServiceAccount(t *testing.T) {
84 b, err := os.ReadFile("../testdata/gdch.json")
85 if err != nil {
86 t.Fatal(err)
87 }
88 got, err := ParseGDCHServiceAccount(b)
89 if err != nil {
90 t.Fatal(err)
91 }
92 want := &GDCHServiceAccountFile{
93 Type: "gdch_service_account",
94 FormatVersion: "1",
95 Project: "fake_project",
96 Name: "sa_name",
97 PrivateKey: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALX0PQoe1igW12ikv1bN/r9lN749y2ijmbc/mFHPyS3hNTyOCjDvBbXYbDhQJzWVUikh4mvGBA07qTj79Xc3yBDfKP2IeyYQIFe0t0zkd7R9Zdn98Y2rIQC47aAbDfubtkU1U72t4zL11kHvoa0/RuFZjncvlr42X7be7lYh4p3NAgMBAAECgYASk5wDw4Az2ZkmeuN6Fk/y9H+Lcb2pskJIXjrL533vrDWGOC48LrsThMQPv8cxBky8HFSEklPpkfTF95tpD43iVwJRB/GrCtGTw65IfJ4/tI09h6zGc4yqvIo1cHX/LQ+SxKLGyir/dQM925rGt/VojxY5ryJR7GLbCzxPnJm/oQJBANwOCO6D2hy1LQYJhXh7O+RLtA/tSnT1xyMQsGT+uUCMiKS2bSKx2wxo9k7h3OegNJIu1q6nZ6AbxDK8H3+d0dUCQQDTrPSXagBxzp8PecbaCHjzNRSQE2in81qYnrAFNB4o3DpHyMMY6s5ALLeHKscEWnqP8Ur6X4PvzZecCWU9BKAZAkAutLPknAuxSCsUOvUfS1i87ex77Ot+w6POp34pEX+UWb+u5iFn2cQacDTHLV1LtE80L8jVLSbrbrlH43H0DjU5AkEAgidhycxS86dxpEljnOMCw8CKoUBd5I880IUahEiUltk7OLJYS/Ts1wbn3kPOVX3wyJs8WBDtBkFrDHW2ezth2QJADj3e1YhMVdjJW5jqwlD/VNddGjgzyunmiZg0uOXsHXbytYmsA545S8KRQFaJKFXYYFo2kOjqOiC1T2cAzMDjCQ==\n-----END PRIVATE KEY-----\n",
98 PrivateKeyID: "abcdef1234567890",
99 CertPath: "cert.pem",
100 TokenURL: "replace_me",
101 }
102 if diff := cmp.Diff(want, got); diff != "" {
103 t.Errorf("(-want +got):\n%s", diff)
104 }
105 }
106
107 func TestParseClientCredential_Web(t *testing.T) {
108 b, err := os.ReadFile("../testdata/clientcreds_web.json")
109 if err != nil {
110 t.Fatal(err)
111 }
112 got, err := ParseClientCredentials(b)
113 if err != nil {
114 t.Fatal(err)
115 }
116 want := &ClientCredentialsFile{
117 Web: &Config3LO{
118 ClientID: "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com",
119 ClientSecret: "3Oknc4jS_wA2r9i",
120 RedirectURIs: []string{"https://www.example.com/oauth2callback"},
121 AuthURI: "https://google.com/o/oauth2/auth",
122 TokenURI: "https://google.com/o/oauth2/token",
123 },
124 }
125 if diff := cmp.Diff(want, got); diff != "" {
126 t.Errorf("(-want +got):\n%s", diff)
127 }
128 }
129
130 func TestParseClientCredential_Installed(t *testing.T) {
131 b, err := os.ReadFile("../testdata/clientcreds_installed.json")
132 if err != nil {
133 t.Fatal(err)
134 }
135 got, err := ParseClientCredentials(b)
136 if err != nil {
137 t.Fatal(err)
138 }
139 want := &ClientCredentialsFile{
140 Installed: &Config3LO{
141 ClientID: "222-installed.apps.googleusercontent.com",
142 ClientSecret: "shhhh",
143 RedirectURIs: []string{"https://www.example.com/oauth2callback"},
144 AuthURI: "https://accounts.google.com/o/oauth2/auth",
145 TokenURI: "https://accounts.google.com/o/oauth2/token",
146 },
147 }
148 if diff := cmp.Diff(want, got); diff != "" {
149 t.Errorf("(-want +got):\n%s", diff)
150 }
151 }
152
153 func TestParseUserCredentials(t *testing.T) {
154 b, err := os.ReadFile("../testdata/user.json")
155 if err != nil {
156 t.Fatal(err)
157 }
158 got, err := ParseUserCredentials(b)
159 if err != nil {
160 t.Fatal(err)
161 }
162 want := &UserCredentialsFile{
163 Type: "authorized_user",
164 ClientID: "abc123.apps.googleusercontent.com",
165 ClientSecret: "shh",
166 QuotaProjectID: "fake_project2",
167 RefreshToken: "refreshing",
168 }
169 if diff := cmp.Diff(want, got); diff != "" {
170 t.Errorf("(-want +got):\n%s", diff)
171 }
172 }
173
174 func TestParseExternalAccount_AWS(t *testing.T) {
175 b, err := os.ReadFile("../testdata/exaccount_aws.json")
176 if err != nil {
177 t.Fatal(err)
178 }
179 got, err := ParseExternalAccount(b)
180 if err != nil {
181 t.Fatal(err)
182 }
183 want := &ExternalAccountFile{
184 Type: "external_account",
185 Audience: "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
186 SubjectTokenType: "urn:ietf:params:aws:token-type:aws4_request",
187 ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$EMAIL:generateAccessToken",
188 TokenURL: "https://sts.googleapis.com/v1/token",
189 CredentialSource: &CredentialSource{
190 URL: "http://169.254.169.254/latest/meta-data/iam/security-credentials",
191 EnvironmentID: "aws1",
192 RegionURL: "http://169.254.169.254/latest/meta-data/placement/availability-zone",
193 RegionalCredVerificationURL: "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
194 IMDSv2SessionTokenURL: "http://169.254.169.254/latest/api/token",
195 },
196 }
197 if diff := cmp.Diff(want, got); diff != "" {
198 t.Errorf("(-want +got):\n%s", diff)
199 }
200 }
201
202 func TestParseExternalAccount_URL(t *testing.T) {
203 b, err := os.ReadFile("../testdata/exaccount_url.json")
204 if err != nil {
205 t.Fatal(err)
206 }
207 got, err := ParseExternalAccount(b)
208 if err != nil {
209 t.Fatal(err)
210 }
211 want := &ExternalAccountFile{
212 Type: "external_account",
213 Audience: "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
214 SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
215 ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$EMAIL:generateAccessToken",
216 TokenURL: "https://sts.googleapis.com/v1/token",
217 CredentialSource: &CredentialSource{
218 URL: "http://localhost:5000/token",
219 Format: &Format{
220 Type: "json",
221 SubjectTokenFieldName: "id_token",
222 },
223 },
224 }
225 if diff := cmp.Diff(want, got); diff != "" {
226 t.Errorf("(-want +got):\n%s", diff)
227 }
228 }
229
230 func TestParseExternalAccount_File(t *testing.T) {
231 b, err := os.ReadFile("../testdata/exaccount_file.json")
232 if err != nil {
233 t.Fatal(err)
234 }
235 got, err := ParseExternalAccount(b)
236 if err != nil {
237 t.Fatal(err)
238 }
239 want := &ExternalAccountFile{
240 Type: "external_account",
241 Audience: "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
242 SubjectTokenType: "urn:ietf:params:oauth:token-type:saml2",
243 ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$EMAIL:generateAccessToken",
244 TokenURL: "https://sts.googleapis.com/v1/token",
245 CredentialSource: &CredentialSource{
246 File: "/var/run/saml/assertion/token",
247 },
248 }
249 if diff := cmp.Diff(want, got); diff != "" {
250 t.Errorf("(-want +got):\n%s", diff)
251 }
252 }
253
254 func TestParseExternalAccount_Cmd(t *testing.T) {
255 b, err := os.ReadFile("../testdata/exaccount_cmd.json")
256 if err != nil {
257 t.Fatal(err)
258 }
259 got, err := ParseExternalAccount(b)
260 if err != nil {
261 t.Fatal(err)
262 }
263 want := &ExternalAccountFile{
264 Type: "external_account",
265 Audience: "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
266 SubjectTokenType: "urn:ietf:params:oauth:token-type:saml2",
267 ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$EMAIL@project.iam.gserviceaccount.com:generateAccessToken",
268 TokenURL: "https://sts.googleapis.com/v1/token",
269 CredentialSource: &CredentialSource{
270 Executable: &ExecutableConfig{
271 Command: "/path/to/executable --arg1=value1 --arg2=value2",
272 OutputFile: "/path/to/cached/credentials",
273 },
274 },
275 }
276 want.CredentialSource.Executable.TimeoutMillis = 5000
277 if diff := cmp.Diff(want, got); diff != "" {
278 t.Errorf("(-want +got):\n%s", diff)
279 }
280 }
281
282 func TestParseExternalAccountAuthorizedUser(t *testing.T) {
283 b, err := os.ReadFile("../testdata/exaccount_user.json")
284 if err != nil {
285 t.Fatal(err)
286 }
287 got, err := ParseExternalAccountAuthorizedUser(b)
288 if err != nil {
289 t.Fatal(err)
290 }
291 want := &ExternalAccountAuthorizedUserFile{
292 Type: "external_account_authorized_user",
293 Audience: "//iam.googleapis.com/locations/global/workforcePools/$POOL_ID/providers/$PROVIDER_ID",
294 ClientID: "abc123.apps.googleusercontent.com",
295 ClientSecret: "shh",
296 RefreshToken: "refreshing",
297 TokenURL: "https://sts.googleapis.com/v1/oauthtoken",
298 TokenInfoURL: "https://sts.googleapis.com/v1/info",
299 RevokeURL: "https://sts.googleapis.com/v1/revoke",
300 QuotaProjectID: "fake_project2",
301 }
302 if diff := cmp.Diff(want, got); diff != "" {
303 t.Errorf("(-want +got):\n%s", diff)
304 }
305 }
306
View as plain text