util.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2022 Google LLC.
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // https://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // Package util provides helper functions for the client.
  14. package util
  15. import (
  16. "encoding/json"
  17. "errors"
  18. "io"
  19. "os"
  20. "os/user"
  21. "path/filepath"
  22. "runtime"
  23. "strings"
  24. )
  25. const configFileName = "certificate_config.json"
  26. // EnterpriseCertificateConfig contains parameters for initializing signer.
  27. type EnterpriseCertificateConfig struct {
  28. Libs Libs `json:"libs"`
  29. }
  30. // Libs specifies the locations of helper libraries.
  31. type Libs struct {
  32. ECP string `json:"ecp"`
  33. }
  34. // ErrConfigUnavailable is a sentinel error that indicates ECP config is unavailable,
  35. // possibly due to entire config missing or missing binary path.
  36. var ErrConfigUnavailable = errors.New("Config is unavailable")
  37. // LoadSignerBinaryPath retrieves the path of the signer binary from the config file.
  38. func LoadSignerBinaryPath(configFilePath string) (path string, err error) {
  39. jsonFile, err := os.Open(configFilePath)
  40. if err != nil {
  41. if errors.Is(err, os.ErrNotExist) {
  42. return "", ErrConfigUnavailable
  43. }
  44. return "", err
  45. }
  46. byteValue, err := io.ReadAll(jsonFile)
  47. if err != nil {
  48. return "", err
  49. }
  50. var config EnterpriseCertificateConfig
  51. err = json.Unmarshal(byteValue, &config)
  52. if err != nil {
  53. return "", err
  54. }
  55. signerBinaryPath := config.Libs.ECP
  56. if signerBinaryPath == "" {
  57. return "", ErrConfigUnavailable
  58. }
  59. signerBinaryPath = strings.ReplaceAll(signerBinaryPath, "~", guessHomeDir())
  60. signerBinaryPath = strings.ReplaceAll(signerBinaryPath, "$HOME", guessHomeDir())
  61. return signerBinaryPath, nil
  62. }
  63. func guessHomeDir() string {
  64. // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
  65. if v := os.Getenv("HOME"); v != "" {
  66. return v
  67. }
  68. // Else, fall back to user.Current:
  69. if u, err := user.Current(); err == nil {
  70. return u.HomeDir
  71. }
  72. return ""
  73. }
  74. func getDefaultConfigFileDirectory() (directory string) {
  75. if runtime.GOOS == "windows" {
  76. return filepath.Join(os.Getenv("APPDATA"), "gcloud")
  77. }
  78. return filepath.Join(guessHomeDir(), ".config/gcloud")
  79. }
  80. // GetDefaultConfigFilePath returns the default path of the enterprise certificate config file created by gCloud.
  81. func GetDefaultConfigFilePath() (path string) {
  82. return filepath.Join(getDefaultConfigFileDirectory(), configFileName)
  83. }
  84. // GetConfigFilePathFromEnv returns the path associated with environment variable GOOGLE_API_CERTIFICATE_CONFIG
  85. func GetConfigFilePathFromEnv() (path string) {
  86. return os.Getenv("GOOGLE_API_CERTIFICATE_CONFIG")
  87. }