mirror of
https://github.com/TwiN/gatus.git
synced 2024-11-07 08:34:15 +01:00
f93cebe715
* feat: add mtls config to client * feat: add mtls config to client * Rework client tls configuration * Rebase (#3) * chore(deps): bump codecov/codecov-action from 3.1.6 to 4.0.1 (#671) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.6 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.6...v4.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(client): enhance HTTP client configuration with proxy support (#668) * feat: enhance HTTP client configuration with proxy support - Add `ProxyURL` field to `Config` struct with YAML tag - Implement proxy URL parsing and setting in `getHTTPClient` method - Add test case for `getHTTPClient` method with custom proxy URL setting - Include `net/url` package in both `config.go` and `config_test.go` files Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> * docs: enhance README with Proxy and OAuth2 Docs - Remove empty lines from README.md - Add documentation for proxy configuration in client examples - Include YAML examples for client using a proxy, custom DNS resolver, OAuth2, and identity-aware proxy configurations in README.md Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> * docs: add proxy client Signed-off-by: appleboy <appleboy.tw@gmail.com> * Update client/config.go * Update README.md * Update client/config_test.go --------- Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> Signed-off-by: appleboy <appleboy.tw@gmail.com> Co-authored-by: TwiN <twin@linux.com> * chore: Update Go to 1.21 * chore(deps): bump github.com/prometheus/client_golang from 1.17.0 to 1.18.0 (#658) chore(deps): bump github.com/prometheus/client_golang Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.17.0 to 1.18.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.17.0...v1.18.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/gofiber/fiber/v2 from 2.49.2 to 2.52.1 (#682) Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.49.2 to 2.52.1. - [Release notes](https://github.com/gofiber/fiber/releases) - [Commits](https://github.com/gofiber/fiber/compare/v2.49.2...v2.52.1) --- updated-dependencies: - dependency-name: github.com/gofiber/fiber/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs(alerting): Fix wrong gitlab terminology (alert key vs. PAT) (#694) Fix wrong term (alert key vs. PAT) * chore(deps): bump github.com/TwiN/deepmerge from 0.2.0 to 0.2.1 (#684) * chore(deps): bump github.com/TwiN/deepmerge from 0.2.0 to 0.2.1 Bumps [github.com/TwiN/deepmerge](https://github.com/TwiN/deepmerge) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/TwiN/deepmerge/releases) - [Commits](https://github.com/TwiN/deepmerge/compare/v0.2.0...v0.2.1) --- updated-dependencies: - dependency-name: github.com/TwiN/deepmerge dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build: Add `go mod tidy` in Dockerfile * ci: Update Go to 1.20 * Update go.mod * Update test.yml --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: TwiN <twin@linux.com> * chore(deps): bump golang.org/x/oauth2 from 0.13.0 to 0.18.0 (#701) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.13.0 to 0.18.0. - [Commits](https://github.com/golang/oauth2/compare/v0.13.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add mtls config to client feat: add mtls config to client Rework client tls configuration --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> Signed-off-by: appleboy <appleboy.tw@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com> Co-authored-by: TwiN <twin@linux.com> Co-authored-by: Salim B <git@salim.space> * Rebase (#4) * chore(deps): bump codecov/codecov-action from 3.1.6 to 4.0.1 (#671) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.6 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.6...v4.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(client): enhance HTTP client configuration with proxy support (#668) * feat: enhance HTTP client configuration with proxy support - Add `ProxyURL` field to `Config` struct with YAML tag - Implement proxy URL parsing and setting in `getHTTPClient` method - Add test case for `getHTTPClient` method with custom proxy URL setting - Include `net/url` package in both `config.go` and `config_test.go` files Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> * docs: enhance README with Proxy and OAuth2 Docs - Remove empty lines from README.md - Add documentation for proxy configuration in client examples - Include YAML examples for client using a proxy, custom DNS resolver, OAuth2, and identity-aware proxy configurations in README.md Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> * docs: add proxy client Signed-off-by: appleboy <appleboy.tw@gmail.com> * Update client/config.go * Update README.md * Update client/config_test.go --------- Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> Signed-off-by: appleboy <appleboy.tw@gmail.com> Co-authored-by: TwiN <twin@linux.com> * chore: Update Go to 1.21 * chore(deps): bump github.com/prometheus/client_golang from 1.17.0 to 1.18.0 (#658) chore(deps): bump github.com/prometheus/client_golang Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.17.0 to 1.18.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.17.0...v1.18.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/gofiber/fiber/v2 from 2.49.2 to 2.52.1 (#682) Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.49.2 to 2.52.1. - [Release notes](https://github.com/gofiber/fiber/releases) - [Commits](https://github.com/gofiber/fiber/compare/v2.49.2...v2.52.1) --- updated-dependencies: - dependency-name: github.com/gofiber/fiber/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs(alerting): Fix wrong gitlab terminology (alert key vs. PAT) (#694) Fix wrong term (alert key vs. PAT) * chore(deps): bump github.com/TwiN/deepmerge from 0.2.0 to 0.2.1 (#684) * chore(deps): bump github.com/TwiN/deepmerge from 0.2.0 to 0.2.1 Bumps [github.com/TwiN/deepmerge](https://github.com/TwiN/deepmerge) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/TwiN/deepmerge/releases) - [Commits](https://github.com/TwiN/deepmerge/compare/v0.2.0...v0.2.1) --- updated-dependencies: - dependency-name: github.com/TwiN/deepmerge dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build: Add `go mod tidy` in Dockerfile * ci: Update Go to 1.20 * Update go.mod * Update test.yml --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: TwiN <twin@linux.com> * chore(deps): bump golang.org/x/oauth2 from 0.13.0 to 0.18.0 (#701) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.13.0 to 0.18.0. - [Commits](https://github.com/golang/oauth2/compare/v0.13.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add mtls config to client * feat: add mtls config to client * Rework client tls configuration --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> Signed-off-by: appleboy <appleboy.tw@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com> Co-authored-by: TwiN <twin@linux.com> Co-authored-by: Salim B <git@salim.space> * Rebase (#6) * feat(tls): add mtls config to client (#189) --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> Signed-off-by: appleboy <appleboy.tw@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com> Co-authored-by: TwiN <twin@linux.com> Co-authored-by: Salim B <git@salim.space>
345 lines
11 KiB
Go
345 lines
11 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"errors"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strconv"
|
|
"time"
|
|
|
|
"golang.org/x/oauth2"
|
|
"golang.org/x/oauth2/clientcredentials"
|
|
"google.golang.org/api/idtoken"
|
|
)
|
|
|
|
const (
|
|
defaultTimeout = 10 * time.Second
|
|
)
|
|
|
|
var (
|
|
ErrInvalidDNSResolver = errors.New("invalid DNS resolver specified. Required format is {proto}://{ip}:{port}")
|
|
ErrInvalidDNSResolverPort = errors.New("invalid DNS resolver port")
|
|
ErrInvalidClientOAuth2Config = errors.New("invalid oauth2 configuration: must define all fields for client credentials flow (token-url, client-id, client-secret, scopes)")
|
|
ErrInvalidClientIAPConfig = errors.New("invalid Identity-Aware-Proxy configuration: must define all fields for Google Identity-Aware-Proxy programmatic authentication (audience)")
|
|
ErrInvalidClientTLSConfig = errors.New("invalid TLS configuration: certificate-file and private-key-file must be specified")
|
|
|
|
defaultConfig = Config{
|
|
Insecure: false,
|
|
IgnoreRedirect: false,
|
|
Timeout: defaultTimeout,
|
|
Network: "ip",
|
|
}
|
|
)
|
|
|
|
// GetDefaultConfig returns a copy of the default configuration
|
|
func GetDefaultConfig() *Config {
|
|
cfg := defaultConfig
|
|
return &cfg
|
|
}
|
|
|
|
// Config is the configuration for clients
|
|
type Config struct {
|
|
// ProxyURL is the URL of the proxy to use for the client
|
|
ProxyURL string `yaml:"proxy-url,omitempty"`
|
|
|
|
// Insecure determines whether to skip verifying the server's certificate chain and host name
|
|
Insecure bool `yaml:"insecure,omitempty"`
|
|
|
|
// IgnoreRedirect determines whether to ignore redirects (true) or follow them (false, default)
|
|
IgnoreRedirect bool `yaml:"ignore-redirect,omitempty"`
|
|
|
|
// Timeout for the client
|
|
Timeout time.Duration `yaml:"timeout"`
|
|
|
|
// DNSResolver override for the HTTP client
|
|
// Expected format is {protocol}://{host}:{port}, e.g. tcp://8.8.8.8:53
|
|
DNSResolver string `yaml:"dns-resolver,omitempty"`
|
|
|
|
// OAuth2Config is the OAuth2 configuration used for the client.
|
|
//
|
|
// If non-nil, the http.Client returned by getHTTPClient will automatically retrieve a token if necessary.
|
|
// See configureOAuth2 for more details.
|
|
OAuth2Config *OAuth2Config `yaml:"oauth2,omitempty"`
|
|
|
|
// IAPConfig is the Google Cloud Identity-Aware-Proxy configuration used for the client. (e.g. audience)
|
|
IAPConfig *IAPConfig `yaml:"identity-aware-proxy,omitempty"`
|
|
|
|
httpClient *http.Client
|
|
|
|
// Network (ip, ip4 or ip6) for the ICMP client
|
|
Network string `yaml:"network"`
|
|
|
|
// TLS configuration (optional)
|
|
TLS *TLSConfig `yaml:"tls,omitempty"`
|
|
}
|
|
|
|
// DNSResolverConfig is the parsed configuration from the DNSResolver config string.
|
|
type DNSResolverConfig struct {
|
|
Protocol string
|
|
Host string
|
|
Port string
|
|
}
|
|
|
|
// OAuth2Config is the configuration for the OAuth2 client credentials flow
|
|
type OAuth2Config struct {
|
|
TokenURL string `yaml:"token-url"` // e.g. https://dev-12345678.okta.com/token
|
|
ClientID string `yaml:"client-id"`
|
|
ClientSecret string `yaml:"client-secret"`
|
|
Scopes []string `yaml:"scopes"` // e.g. ["openid"]
|
|
}
|
|
|
|
// IAPConfig is the configuration for the Google Cloud Identity-Aware-Proxy
|
|
type IAPConfig struct {
|
|
Audience string `yaml:"audience"` // e.g. "toto.apps.googleusercontent.com"
|
|
}
|
|
|
|
// TLSConfig is the configuration for mTLS configurations
|
|
type TLSConfig struct {
|
|
// CertificateFile is the public certificate for TLS in PEM format.
|
|
CertificateFile string `yaml:"certificate-file,omitempty"`
|
|
|
|
// PrivateKeyFile is the private key file for TLS in PEM format.
|
|
PrivateKeyFile string `yaml:"private-key-file,omitempty"`
|
|
|
|
RenegotiationSupport string `yaml:"renegotiation,omitempty"`
|
|
}
|
|
|
|
// ValidateAndSetDefaults validates the client configuration and sets the default values if necessary
|
|
func (c *Config) ValidateAndSetDefaults() error {
|
|
if c.Timeout < time.Millisecond {
|
|
c.Timeout = 10 * time.Second
|
|
}
|
|
if c.HasCustomDNSResolver() {
|
|
// Validate the DNS resolver now to make sure it will not return an error later.
|
|
if _, err := c.parseDNSResolver(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if c.HasOAuth2Config() && !c.OAuth2Config.isValid() {
|
|
return ErrInvalidClientOAuth2Config
|
|
}
|
|
if c.HasIAPConfig() && !c.IAPConfig.isValid() {
|
|
return ErrInvalidClientIAPConfig
|
|
}
|
|
if c.HasTlsConfig() {
|
|
if err := c.TLS.isValid(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// HasCustomDNSResolver returns whether a custom DNSResolver is configured
|
|
func (c *Config) HasCustomDNSResolver() bool {
|
|
return len(c.DNSResolver) > 0
|
|
}
|
|
|
|
// parseDNSResolver parses the DNS resolver into the DNSResolverConfig struct
|
|
func (c *Config) parseDNSResolver() (*DNSResolverConfig, error) {
|
|
re := regexp.MustCompile(`^(?P<proto>(.*))://(?P<host>[A-Za-z0-9\-\.]+):(?P<port>[0-9]+)?(.*)$`)
|
|
matches := re.FindStringSubmatch(c.DNSResolver)
|
|
if len(matches) == 0 {
|
|
return nil, ErrInvalidDNSResolver
|
|
}
|
|
r := make(map[string]string)
|
|
for i, k := range re.SubexpNames() {
|
|
if i != 0 && k != "" {
|
|
r[k] = matches[i]
|
|
}
|
|
}
|
|
port, err := strconv.Atoi(r["port"])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if port < 1 || port > 65535 {
|
|
return nil, ErrInvalidDNSResolverPort
|
|
}
|
|
return &DNSResolverConfig{
|
|
Protocol: r["proto"],
|
|
Host: r["host"],
|
|
Port: r["port"],
|
|
}, nil
|
|
}
|
|
|
|
// HasOAuth2Config returns true if the client has OAuth2 configuration parameters
|
|
func (c *Config) HasOAuth2Config() bool {
|
|
return c.OAuth2Config != nil
|
|
}
|
|
|
|
// HasIAPConfig returns true if the client has IAP configuration parameters
|
|
func (c *Config) HasIAPConfig() bool {
|
|
return c.IAPConfig != nil
|
|
}
|
|
|
|
// HasTlsConfig returns true if the client has client certificate parameters
|
|
func (c *Config) HasTlsConfig() bool {
|
|
return c.TLS != nil && len(c.TLS.CertificateFile) > 0 && len(c.TLS.PrivateKeyFile) > 0
|
|
}
|
|
|
|
// isValid() returns true if the IAP configuration is valid
|
|
func (c *IAPConfig) isValid() bool {
|
|
return len(c.Audience) > 0
|
|
}
|
|
|
|
// isValid() returns true if the OAuth2 configuration is valid
|
|
func (c *OAuth2Config) isValid() bool {
|
|
return len(c.TokenURL) > 0 && len(c.ClientID) > 0 && len(c.ClientSecret) > 0 && len(c.Scopes) > 0
|
|
}
|
|
|
|
// isValid() returns nil if the client tls certificates are valid, otherwise returns an error
|
|
func (t *TLSConfig) isValid() error {
|
|
if len(t.CertificateFile) > 0 && len(t.PrivateKeyFile) > 0 {
|
|
_, err := tls.LoadX509KeyPair(t.CertificateFile, t.PrivateKeyFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
return ErrInvalidClientTLSConfig
|
|
}
|
|
|
|
// GetHTTPClient return an HTTP client matching the Config's parameters.
|
|
func (c *Config) getHTTPClient() *http.Client {
|
|
tlsConfig := &tls.Config{
|
|
InsecureSkipVerify: c.Insecure,
|
|
}
|
|
if c.HasTlsConfig() && c.TLS.isValid() == nil {
|
|
tlsConfig = configureTLS(tlsConfig, *c.TLS)
|
|
}
|
|
if c.httpClient == nil {
|
|
c.httpClient = &http.Client{
|
|
Timeout: c.Timeout,
|
|
Transport: &http.Transport{
|
|
MaxIdleConns: 100,
|
|
MaxIdleConnsPerHost: 20,
|
|
Proxy: http.ProxyFromEnvironment,
|
|
TLSClientConfig: tlsConfig,
|
|
},
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
if c.IgnoreRedirect {
|
|
// Don't follow redirects
|
|
return http.ErrUseLastResponse
|
|
}
|
|
// Follow redirects
|
|
return nil
|
|
},
|
|
}
|
|
if c.ProxyURL != "" {
|
|
proxyURL, err := url.Parse(c.ProxyURL)
|
|
if err != nil {
|
|
log.Println("[client.getHTTPClient] THIS SHOULD NOT HAPPEN. Silently ignoring custom proxy due to error:", err.Error())
|
|
} else {
|
|
c.httpClient.Transport.(*http.Transport).Proxy = http.ProxyURL(proxyURL)
|
|
}
|
|
}
|
|
if c.HasCustomDNSResolver() {
|
|
dnsResolver, err := c.parseDNSResolver()
|
|
if err != nil {
|
|
// We're ignoring the error, because it should have been validated on startup ValidateAndSetDefaults.
|
|
// It shouldn't happen, but if it does, we'll log it... Better safe than sorry ;)
|
|
log.Println("[client.getHTTPClient] THIS SHOULD NOT HAPPEN. Silently ignoring invalid DNS resolver due to error:", err.Error())
|
|
} else {
|
|
dialer := &net.Dialer{
|
|
Resolver: &net.Resolver{
|
|
PreferGo: true,
|
|
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
d := net.Dialer{}
|
|
return d.DialContext(ctx, dnsResolver.Protocol, dnsResolver.Host+":"+dnsResolver.Port)
|
|
},
|
|
},
|
|
}
|
|
c.httpClient.Transport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
return dialer.DialContext(ctx, network, addr)
|
|
}
|
|
}
|
|
}
|
|
if c.HasOAuth2Config() && c.HasIAPConfig() {
|
|
log.Println("[client.getHTTPClient] Error: Both Identity-Aware-Proxy and Oauth2 configuration are present.")
|
|
} else if c.HasOAuth2Config() {
|
|
c.httpClient = configureOAuth2(c.httpClient, *c.OAuth2Config)
|
|
} else if c.HasIAPConfig() {
|
|
c.httpClient = configureIAP(c.httpClient, *c.IAPConfig)
|
|
}
|
|
}
|
|
return c.httpClient
|
|
}
|
|
|
|
// validateIAPToken returns a boolean that will define if the google identity-aware-proxy token can be fetch
|
|
// and if is it valid.
|
|
func validateIAPToken(ctx context.Context, c IAPConfig) bool {
|
|
ts, err := idtoken.NewTokenSource(ctx, c.Audience)
|
|
if err != nil {
|
|
log.Println("[client.ValidateIAPToken] Claiming Identity token failed. error:", err.Error())
|
|
return false
|
|
}
|
|
tok, err := ts.Token()
|
|
if err != nil {
|
|
log.Println("[client.ValidateIAPToken] Get Identity-Aware-Proxy token failed. error:", err.Error())
|
|
return false
|
|
}
|
|
payload, err := idtoken.Validate(ctx, tok.AccessToken, c.Audience)
|
|
_ = payload
|
|
if err != nil {
|
|
log.Println("[client.ValidateIAPToken] Token Validation failed. error:", err.Error())
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// configureIAP returns an HTTP client that will obtain and refresh Identity-Aware-Proxy tokens as necessary.
|
|
// The returned Client and its Transport should not be modified.
|
|
func configureIAP(httpClient *http.Client, c IAPConfig) *http.Client {
|
|
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, httpClient)
|
|
if validateIAPToken(ctx, c) {
|
|
ts, err := idtoken.NewTokenSource(ctx, c.Audience)
|
|
if err != nil {
|
|
log.Println("[client.ConfigureIAP] Claiming Token Source failed. error:", err.Error())
|
|
return httpClient
|
|
}
|
|
client := oauth2.NewClient(ctx, ts)
|
|
client.Timeout = httpClient.Timeout
|
|
return client
|
|
}
|
|
return httpClient
|
|
}
|
|
|
|
// configureOAuth2 returns an HTTP client that will obtain and refresh tokens as necessary.
|
|
// The returned Client and its Transport should not be modified.
|
|
func configureOAuth2(httpClient *http.Client, c OAuth2Config) *http.Client {
|
|
oauth2cfg := clientcredentials.Config{
|
|
ClientID: c.ClientID,
|
|
ClientSecret: c.ClientSecret,
|
|
Scopes: c.Scopes,
|
|
TokenURL: c.TokenURL,
|
|
}
|
|
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, httpClient)
|
|
client := oauth2cfg.Client(ctx)
|
|
client.Timeout = httpClient.Timeout
|
|
return client
|
|
}
|
|
|
|
// configureTLS returns a TLS Config that will enable mTLS
|
|
func configureTLS(tlsConfig *tls.Config, c TLSConfig) *tls.Config {
|
|
clientTLSCert, err := tls.LoadX509KeyPair(c.CertificateFile, c.PrivateKeyFile)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
tlsConfig.Certificates = []tls.Certificate{clientTLSCert}
|
|
tlsConfig.Renegotiation = tls.RenegotiateNever
|
|
|
|
renegotionSupport := map[string]tls.RenegotiationSupport{
|
|
"once": tls.RenegotiateOnceAsClient,
|
|
"freely": tls.RenegotiateFreelyAsClient,
|
|
"never": tls.RenegotiateNever,
|
|
}
|
|
if val, ok := renegotionSupport[c.RenegotiationSupport]; ok {
|
|
tlsConfig.Renegotiation = val
|
|
}
|
|
return tlsConfig
|
|
}
|