credsfile.go

  1// Copyright 2023 Google LLC
  2//
  3// Licensed under the Apache License, Version 2.0 (the "License");
  4// you may not use this file except in compliance with the License.
  5// You may obtain a copy of the License at
  6//
  7//      http://www.apache.org/licenses/LICENSE-2.0
  8//
  9// Unless required by applicable law or agreed to in writing, software
 10// distributed under the License is distributed on an "AS IS" BASIS,
 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12// See the License for the specific language governing permissions and
 13// limitations under the License.
 14
 15// Package credsfile is meant to hide implementation details from the pubic
 16// surface of the detect package. It should not import any other packages in
 17// this module. It is located under the main internal package so other
 18// sub-packages can use these parsed types as well.
 19package credsfile
 20
 21import (
 22	"os"
 23	"os/user"
 24	"path/filepath"
 25	"runtime"
 26)
 27
 28const (
 29	// GoogleAppCredsEnvVar is the environment variable for setting the
 30	// application default credentials.
 31	GoogleAppCredsEnvVar = "GOOGLE_APPLICATION_CREDENTIALS"
 32	userCredsFilename    = "application_default_credentials.json"
 33)
 34
 35// CredentialType represents different credential filetypes Google credentials
 36// can be.
 37type CredentialType int
 38
 39const (
 40	// UnknownCredType is an unidentified file type.
 41	UnknownCredType CredentialType = iota
 42	// UserCredentialsKey represents a user creds file type.
 43	UserCredentialsKey
 44	// ServiceAccountKey represents a service account file type.
 45	ServiceAccountKey
 46	// ImpersonatedServiceAccountKey represents a impersonated service account
 47	// file type.
 48	ImpersonatedServiceAccountKey
 49	// ExternalAccountKey represents a external account file type.
 50	ExternalAccountKey
 51	// GDCHServiceAccountKey represents a GDCH file type.
 52	GDCHServiceAccountKey
 53	// ExternalAccountAuthorizedUserKey represents a external account authorized
 54	// user file type.
 55	ExternalAccountAuthorizedUserKey
 56)
 57
 58// parseCredentialType returns the associated filetype based on the parsed
 59// typeString provided.
 60func parseCredentialType(typeString string) CredentialType {
 61	switch typeString {
 62	case "service_account":
 63		return ServiceAccountKey
 64	case "authorized_user":
 65		return UserCredentialsKey
 66	case "impersonated_service_account":
 67		return ImpersonatedServiceAccountKey
 68	case "external_account":
 69		return ExternalAccountKey
 70	case "external_account_authorized_user":
 71		return ExternalAccountAuthorizedUserKey
 72	case "gdch_service_account":
 73		return GDCHServiceAccountKey
 74	default:
 75		return UnknownCredType
 76	}
 77}
 78
 79// GetFileNameFromEnv returns the override if provided or detects a filename
 80// from the environment.
 81func GetFileNameFromEnv(override string) string {
 82	if override != "" {
 83		return override
 84	}
 85	return os.Getenv(GoogleAppCredsEnvVar)
 86}
 87
 88// GetWellKnownFileName tries to locate the filepath for the user credential
 89// file based on the environment.
 90func GetWellKnownFileName() string {
 91	if runtime.GOOS == "windows" {
 92		return filepath.Join(os.Getenv("APPDATA"), "gcloud", userCredsFilename)
 93	}
 94	return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", userCredsFilename)
 95}
 96
 97// guessUnixHomeDir default to checking for HOME, but not all unix systems have
 98// this set, do have a fallback.
 99func guessUnixHomeDir() string {
100	if v := os.Getenv("HOME"); v != "" {
101		return v
102	}
103	if u, err := user.Current(); err == nil {
104		return u.HomeDir
105	}
106	return ""
107}