github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/securehttp/caller.go (about) 1 package securehttp 2 3 import ( 4 "net/http" 5 "time" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/certloader" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/oauth" 10 11 "github.com/pkg/errors" 12 13 "github.com/kyma-incubator/compass/components/director/pkg/auth" 14 director_http "github.com/kyma-incubator/compass/components/director/pkg/http" 15 ) 16 17 // CallerConfig holds the configuration for Caller 18 type CallerConfig struct { 19 Credentials auth.Credentials 20 ClientTimeout time.Duration 21 22 SkipSSLValidation bool 23 Cache certloader.Cache 24 ExternalClientCertSecretName string 25 } 26 27 // Caller can be used to call secured http endpoints with given credentials 28 type Caller struct { 29 Credentials auth.Credentials 30 31 Provider director_http.AuthorizationProvider 32 client *http.Client 33 } 34 35 // NewCaller creates a new Caller 36 func NewCaller(config CallerConfig) (*Caller, error) { 37 c := &Caller{ 38 Credentials: config.Credentials, 39 client: &http.Client{Timeout: config.ClientTimeout}, 40 } 41 42 switch config.Credentials.Type() { 43 case auth.BasicCredentialType: 44 c.Provider = auth.NewBasicAuthorizationProvider() 45 case auth.OAuthCredentialType: 46 c.Provider = auth.NewTokenAuthorizationProvider(&http.Client{Timeout: config.ClientTimeout}) 47 case auth.OAuthMtlsCredentialType: 48 oauthCfg := oauth.Config{ 49 TokenRequestTimeout: config.ClientTimeout, 50 SkipSSLValidation: config.SkipSSLValidation, 51 } 52 credentials, ok := config.Credentials.Get().(*auth.OAuthMtlsCredentials) 53 if !ok { 54 return nil, errors.New("failed to cast credentials to mtls oauth credentials type") 55 } 56 c.Provider = auth.NewMtlsTokenAuthorizationProvider(oauthCfg, config.ExternalClientCertSecretName, credentials.CertCache, auth.DefaultMtlsClientCreator) 57 } 58 c.client.Transport = director_http.NewCorrelationIDTransport(director_http.NewSecuredTransport(director_http.NewHTTPTransportWrapper(http.DefaultTransport.(*http.Transport)), c.Provider)) 59 return c, nil 60 } 61 62 // Call executes a http call with the configured credentials 63 func (c *Caller) Call(req *http.Request) (*http.Response, error) { 64 req = c.addCredentialsToContext(req) 65 resp, err := c.client.Do(req) 66 if err != nil { 67 return nil, errors.Wrapf(err, "while executing call to %s: ", req.URL) 68 } 69 return resp, nil 70 } 71 72 func (c *Caller) addCredentialsToContext(req *http.Request) *http.Request { 73 authCtx := req.Context() 74 authCtx = auth.SaveToContext(authCtx, c.Credentials) 75 return req.WithContext(authCtx) 76 }