github.com/Venafi/vcert/v5@v5.10.2/pkg/venafi/firefly/fireflyServer_test.go (about)

     1  package firefly
     2  
     3  import (
     4  	"encoding/json"
     5  	"log"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"reflect"
     9  	"strings"
    10  )
    11  
    12  const (
    13  	TestingPolicyName        = "myPolicy"
    14  	TestingFailingPolicyName = "failingPolicy" // used to return a corrupted certificate
    15  )
    16  
    17  func newFireflyMockServer() *FireflyMockServer {
    18  	certReqPath := "/v1/certificaterequest"
    19  	certSignReqPath := "/v1/certificatesigningrequest"
    20  	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    21  		//getting the AccessToken
    22  		accessToken := getAccessToken(r)
    23  		if accessToken == "" {
    24  			writeError(w, http.StatusBadRequest, "no-accessToken", "the access token was not provided")
    25  			return
    26  		}
    27  
    28  		//validating the AccessToken
    29  		if accessToken != TestingAccessToken {
    30  			writeError(w, http.StatusUnauthorized, "no-authorized", "the access token is not valid")
    31  			return
    32  		}
    33  
    34  		switch strings.TrimSpace(r.URL.Path) {
    35  		case certReqPath:
    36  			processCertificateRequest(w, r)
    37  		case certSignReqPath:
    38  			processCertificateSigningRequest(w, r)
    39  		default:
    40  			http.NotFoundHandler().ServeHTTP(w, r)
    41  		}
    42  	}))
    43  	//creating and returning the Firefly server
    44  	return &FireflyMockServer{
    45  		server:          server,
    46  		serverURL:       server.URL,
    47  		certReqPath:     certReqPath,
    48  		certSignReqPath: certSignReqPath,
    49  	}
    50  }
    51  
    52  type FireflyMockServer struct {
    53  	server          *httptest.Server
    54  	serverURL       string
    55  	certReqPath     string
    56  	certSignReqPath string
    57  }
    58  
    59  func getAccessToken(r *http.Request) string {
    60  	//getting the BearerToken
    61  	bearerToken := r.Header.Get("Authorization")
    62  	if bearerToken == "" {
    63  		return ""
    64  	}
    65  
    66  	accessToken, found := strings.CutPrefix(bearerToken, "Bearer ")
    67  	if !found {
    68  		return ""
    69  	}
    70  	return accessToken
    71  }
    72  
    73  func processCertificateRequest(w http.ResponseWriter, r *http.Request) {
    74  	var certReq certificateRequest
    75  
    76  	if r.Method != http.MethodPost {
    77  		http.NotFoundHandler().ServeHTTP(w, r)
    78  		return
    79  	}
    80  
    81  	// Try to decode the request body into the struct. If there is an error,
    82  	// respond to the client with the error message and a 400 status code.
    83  	err := json.NewDecoder(r.Body).Decode(&certReq)
    84  	if err != nil {
    85  		writeError(w, http.StatusBadRequest, err.Error(), "")
    86  		return
    87  	}
    88  
    89  	//validating that the subject was provided given is required
    90  	if reflect.DeepEqual(certReq.Subject, Subject{}) {
    91  		writeError(w, http.StatusBadRequest, "no-subject", "the subject was not provided")
    92  		return
    93  	}
    94  
    95  	//validating that the policy name was provided given is required
    96  	if certReq.PolicyName == "" {
    97  		writeError(w, http.StatusBadRequest, "no-policyName", "the policy name was not provided")
    98  		return
    99  	}
   100  
   101  	if certReq.PolicyName != TestingPolicyName && certReq.PolicyName != TestingFailingPolicyName {
   102  		writeError(w, http.StatusBadRequest, "invalid-policyName", "the policy name is not valid")
   103  		return
   104  	}
   105  
   106  	var certChain = cert_test
   107  	if certReq.PolicyName == TestingFailingPolicyName {
   108  		certChain = cert_test_corrupted
   109  	}
   110  
   111  	//Headers must be set before the status and the body are written to the response.
   112  	w.Header().Set("Content-Type", "application/json")
   113  	w.WriteHeader(http.StatusOK)
   114  
   115  	certificateRequestResponse := certificateRequestResponse{
   116  		CertificateChain: certChain,
   117  		PrivateKey:       pk_test,
   118  	}
   119  
   120  	jsonResp, err := json.Marshal(certificateRequestResponse)
   121  	if err != nil {
   122  		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
   123  	}
   124  	w.Write(jsonResp)
   125  }
   126  
   127  func processCertificateSigningRequest(w http.ResponseWriter, r *http.Request) {
   128  	var certReq certificateRequest
   129  
   130  	if r.Method != http.MethodPost {
   131  		http.NotFoundHandler().ServeHTTP(w, r)
   132  		return
   133  	}
   134  
   135  	// Try to decode the request body into the struct. If there is an error,
   136  	// respond to the client with the error message and a 400 status code.
   137  	err := json.NewDecoder(r.Body).Decode(&certReq)
   138  	if err != nil {
   139  		writeError(w, http.StatusBadRequest, err.Error(), "")
   140  		return
   141  	}
   142  
   143  	//validating that the CSR was provided given is required
   144  	if certReq.CSR == "" {
   145  		writeError(w, http.StatusBadRequest, "no-csr", "the CSR was not provided")
   146  		return
   147  	}
   148  
   149  	//validating that the policy name was provided given is required
   150  	if certReq.PolicyName == "" {
   151  		writeError(w, http.StatusBadRequest, "no-policyName", "the policy name was not provided")
   152  		return
   153  	}
   154  
   155  	if certReq.PolicyName != TestingPolicyName && certReq.PolicyName != TestingFailingPolicyName {
   156  		writeError(w, http.StatusBadRequest, "invalid-policyName", "the policy name is not valid")
   157  		return
   158  	}
   159  
   160  	var certChain = cert_test
   161  	if certReq.PolicyName == TestingFailingPolicyName {
   162  		certChain = cert_test_corrupted
   163  	}
   164  
   165  	//Headers must be set before the status and the body are written to the response.
   166  	w.Header().Set("Content-Type", "application/json")
   167  	w.WriteHeader(http.StatusOK)
   168  
   169  	certificateRequestResponse := certificateRequestResponse{
   170  		CertificateChain: certChain,
   171  	}
   172  
   173  	jsonResp, err := json.Marshal(certificateRequestResponse)
   174  	if err != nil {
   175  		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
   176  	}
   177  	w.Write(jsonResp)
   178  }