github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/http/secured_transport.go (about)

     1  /*
     2   * Copyright 2020 The Compass Authors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package http
    18  
    19  import (
    20  	"context"
    21  	"net/http"
    22  
    23  	"github.com/kyma-incubator/compass/components/director/pkg/log"
    24  	"github.com/pkg/errors"
    25  )
    26  
    27  // AuthorizationProvider missing godoc
    28  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . AuthorizationProvider
    29  type AuthorizationProvider interface {
    30  	Name() string
    31  	Matches(ctx context.Context) bool
    32  	GetAuthorization(ctx context.Context) (string, error)
    33  }
    34  
    35  // SecuredTransport missing godoc
    36  type SecuredTransport struct {
    37  	roundTripper           HTTPRoundTripper
    38  	authorizationProviders []AuthorizationProvider
    39  }
    40  
    41  // NewSecuredTransport missing godoc
    42  func NewSecuredTransport(roundTripper HTTPRoundTripper, providers ...AuthorizationProvider) *SecuredTransport {
    43  	return &SecuredTransport{
    44  		roundTripper:           roundTripper,
    45  		authorizationProviders: providers,
    46  	}
    47  }
    48  
    49  // RoundTrip missing godoc
    50  func (c *SecuredTransport) RoundTrip(request *http.Request) (*http.Response, error) {
    51  	logger := log.C(request.Context())
    52  
    53  	authorization, err := c.getAuthorizationFromProvider(request.Context())
    54  	if err != nil {
    55  		logger.Errorf("Could not prepare authorization for request: %s", err.Error())
    56  		return nil, err
    57  	}
    58  
    59  	if authorization != "" {
    60  		logger.Debug("Successfully prepared authorization for request")
    61  		request.Header.Set("Authorization", authorization)
    62  	}
    63  
    64  	return c.roundTripper.RoundTrip(request)
    65  }
    66  
    67  // Clone clones the underlying transport
    68  func (c *SecuredTransport) Clone() HTTPRoundTripper {
    69  	return &SecuredTransport{
    70  		roundTripper:           c.roundTripper.Clone(),
    71  		authorizationProviders: c.authorizationProviders,
    72  	}
    73  }
    74  
    75  // GetTransport returns the underlying transport.
    76  func (c *SecuredTransport) GetTransport() *http.Transport {
    77  	return c.roundTripper.GetTransport()
    78  }
    79  
    80  func (c *SecuredTransport) getAuthorizationFromProvider(ctx context.Context) (string, error) {
    81  	for _, authProvider := range c.authorizationProviders {
    82  		if !authProvider.Matches(ctx) {
    83  			continue
    84  		}
    85  		log.C(ctx).Debugf("Successfully matched '%s' authorization provider", authProvider.Name())
    86  
    87  		authorization, err := authProvider.GetAuthorization(ctx)
    88  		if err != nil {
    89  			return "", errors.Wrap(err, "error while obtaining authorization")
    90  		}
    91  
    92  		return authorization, nil
    93  	}
    94  
    95  	log.C(ctx).Info("Context did not match any authorization provider.")
    96  	return "", nil
    97  }