github.com/openshift-online/ocm-sdk-go@v0.1.473/redirect_test.go (about)

     1  /*
     2  Copyright (c) 2020 Red Hat, Inc.
     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  // This file contains tests for the follow redirects support.
    18  
    19  package sdk
    20  
    21  import (
    22  	"net/http"
    23  	"net/url"
    24  	"os"
    25  	"time"
    26  
    27  	"github.com/onsi/gomega/ghttp"
    28  
    29  	. "github.com/onsi/ginkgo/v2/dsl/core"             // nolint
    30  	. "github.com/onsi/gomega"                         // nolint
    31  	. "github.com/openshift-online/ocm-sdk-go/testing" // nolint
    32  )
    33  
    34  var _ = Describe("Redirect", func() {
    35  	// Tokens used during the tests:
    36  	var accessToken string
    37  	var refreshToken string
    38  
    39  	// Servers used during the tests:
    40  	var oidServer *ghttp.Server
    41  	var redirectServer *ghttp.Server
    42  	var realServer *ghttp.Server
    43  
    44  	// Names of the temporary files containing the CAs for the servers:
    45  	var oidCA string
    46  	var redirectCA string
    47  	var realCA string
    48  
    49  	// URLs of the servers:
    50  	var oidURL string
    51  	var redirectURL string
    52  	var realURL string
    53  
    54  	// Connection used for the tests:
    55  	var connection *Connection
    56  
    57  	BeforeEach(func() {
    58  		var err error
    59  
    60  		// Create the tokens:
    61  		accessToken = MakeTokenString("Bearer", 5*time.Minute)
    62  		refreshToken = MakeTokenString("Refresh", 10*time.Hour)
    63  
    64  		// Create the OpenID server:
    65  		oidServer, oidCA = MakeTCPTLSServer()
    66  		oidServer.AppendHandlers(
    67  			ghttp.CombineHandlers(
    68  				RespondWithAccessAndRefreshTokens(accessToken, refreshToken),
    69  			),
    70  		)
    71  		oidURL = oidServer.URL()
    72  
    73  		// Create the API servers:
    74  		redirectServer, redirectCA = MakeTCPTLSServer()
    75  		redirectURL = redirectServer.URL()
    76  		realServer, realCA = MakeTCPTLSServer()
    77  		realURL = realServer.URL()
    78  
    79  		// Configure the real server so that it verifies that the request is
    80  		// received:
    81  		realServer.AppendHandlers(
    82  			ghttp.CombineHandlers(
    83  				ghttp.VerifyRequest(http.MethodGet, "/api/clusters_mgmt/v1"),
    84  				RespondWithJSON(http.StatusOK, "{}"),
    85  			),
    86  		)
    87  
    88  		// Create the connection:
    89  		connection, err = NewConnectionBuilder().
    90  			Logger(logger).
    91  			TokenURL(oidURL).
    92  			Tokens(accessToken, refreshToken).
    93  			URL(redirectURL).
    94  			TrustedCAFile(oidCA).
    95  			TrustedCAFile(redirectCA).
    96  			TrustedCAFile(realCA).
    97  			Build()
    98  		Expect(err).ToNot(HaveOccurred())
    99  	})
   100  
   101  	AfterEach(func() {
   102  		var err error
   103  
   104  		// Close the connection:
   105  		err = connection.Close()
   106  		Expect(err).ToNot(HaveOccurred())
   107  
   108  		// Stop the servers:
   109  		oidServer.Close()
   110  		redirectServer.Close()
   111  		realServer.Close()
   112  
   113  		// Remove the temporary CA files:
   114  		err = os.Remove(oidCA)
   115  		Expect(err).ToNot(HaveOccurred())
   116  		err = os.Remove(redirectCA)
   117  		Expect(err).ToNot(HaveOccurred())
   118  		err = os.Remove(realCA)
   119  		Expect(err).ToNot(HaveOccurred())
   120  	})
   121  
   122  	Describe("Untyped get", func() {
   123  		It("Honours permanent redirect", func() {
   124  			// Configure the redirect server so that it redirects to the real server:
   125  			redirectServer.AppendHandlers(
   126  				RespondWithPermanentRedirect(realURL),
   127  			)
   128  
   129  			// Send the request:
   130  			_, err := connection.Get().
   131  				Path("/api/clusters_mgmt/v1").
   132  				Send()
   133  			Expect(err).ToNot(HaveOccurred())
   134  		})
   135  
   136  		It("Honours temporary redirect", func() {
   137  			// Configure the redirect server so that it redirects to the real server:
   138  			redirectServer.AppendHandlers(
   139  				RespondWithTemporaryRedirect(realURL),
   140  			)
   141  
   142  			// Send the request:
   143  			_, err := connection.Get().
   144  				Path("/api/clusters_mgmt/v1").
   145  				Send()
   146  			Expect(err).ToNot(HaveOccurred())
   147  		})
   148  	})
   149  
   150  	Describe("Typed get", func() {
   151  		It("Honours permanent redirect", func() {
   152  			// Configure the redirect server so that it redirects to the rea server:
   153  			redirectServer.AppendHandlers(
   154  				RespondWithPermanentRedirect(realURL),
   155  			)
   156  
   157  			// Send the request:
   158  			_, err := connection.ClustersMgmt().V1().Get().Send()
   159  			Expect(err).ToNot(HaveOccurred())
   160  		})
   161  
   162  		It("Honours temporary redirect", func() {
   163  			// Configure the redirect server so that it redirects to the real server:
   164  			redirectServer.AppendHandlers(
   165  				RespondWithTemporaryRedirect(realURL),
   166  			)
   167  
   168  			// Send the request:
   169  			_, err := connection.ClustersMgmt().V1().Get().Send()
   170  			Expect(err).ToNot(HaveOccurred())
   171  		})
   172  	})
   173  })
   174  
   175  // RespondWithPermanentRedirect responds with a permanent redirect to the given target URL,
   176  // changing the scheme, host and port number but preserving the path of the original request.
   177  func RespondWithPermanentRedirect(target string) http.HandlerFunc {
   178  	return RespondWithRedirect(http.StatusPermanentRedirect, target)
   179  }
   180  
   181  // RespondWithTemporaryRedirect responds with a permanent redirect to the given target URL,
   182  // changing the scheme, host and port number but preserving the path of the original request.
   183  func RespondWithTemporaryRedirect(target string) http.HandlerFunc {
   184  	return RespondWithRedirect(http.StatusTemporaryRedirect, target)
   185  }
   186  
   187  // RespondTemporaryRedirect responds with a redirect with the given code to the given target URL,
   188  // changing the scheme, host and port number but preserving the path of the original request.
   189  func RespondWithRedirect(code int, target string) http.HandlerFunc {
   190  	return func(w http.ResponseWriter, r *http.Request) {
   191  		parsed, err := url.Parse(target)
   192  		Expect(err).ToNot(HaveOccurred())
   193  		location := r.URL
   194  		location.Scheme = parsed.Scheme
   195  		location.Host = parsed.Host
   196  		w.Header().Set("Location", location.String())
   197  		w.WriteHeader(code)
   198  	}
   199  }