Skip to content

Commit

Permalink
Solved Issue by checking existent SSL certificates on site creation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jonxir authored Dec 12, 2024
1 parent 3faa55b commit fbbcca3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
18 changes: 17 additions & 1 deletion incapsula/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ func (c *Client) PostFormWithHeaders(url string, data url.Values, operation stri
return c.executeRequest(req)
}

func (c *Client) GetWithHeaders(url string, queryParams url.Values, operation string) (*http.Response, error) {
reqURL := url
if len(queryParams) > 0 {
reqURL = fmt.Sprintf("%s?%s", url, queryParams.Encode())
}
req, err := http.NewRequest(http.MethodGet, reqURL, nil)
if err != nil {
return nil, fmt.Errorf("Error preparing request: %s", err)
}

SetHeaders(c, req, contentTypeApplicationJson, operation, nil)
return c.executeRequest(req)
}

func (c *Client) DoJsonRequestWithCustomHeaders(method string, url string, data []byte, headers map[string]string, operation string) (*http.Response, error) {
req, err := PrepareJsonRequest(method, url, data)
if err != nil {
Expand Down Expand Up @@ -179,7 +193,9 @@ func PrepareJsonRequest(method string, url string, data []byte) (*http.Request,
}

func SetHeaders(c *Client, req *http.Request, contentType string, operation string, customHeaders map[string]string) {
req.Header.Set("Content-Type", contentType)
if req.Method != http.MethodGet {
req.Header.Set("Content-Type", contentType)
}
req.Header.Set("x-api-id", c.config.APIID)
req.Header.Set("x-api-key", c.config.APIKey)
req.Header.Set("x-tf-provider-ver", c.providerVersion)
Expand Down
52 changes: 52 additions & 0 deletions incapsula/client_site.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const endpointSiteAdd = "sites/add"
const endpointSiteStatus = "sites/status"
const endpointSiteUpdate = "sites/configure"
const endpointSiteDelete = "sites/delete"
const endpointCertDetails = "certificates-ui/v3/certificates"

// SiteAddResponse contains the relevant site information when adding an Incapsula managed site
type SiteAddResponse struct {
Expand Down Expand Up @@ -210,6 +211,21 @@ type SiteStatusResponse struct {
} `json:"debug_info"`
}

// SAN contains the relevant status information when parsing the SANs
type SAN struct {
Status string `json:"status"`
}

// DataItem contains the relevant SAN information when parsing the data
type DataItem struct {
Sans []SAN `json:"sans"`
}

// Response contains the relevant data from the response when checking for SSL certificates
type Response struct {
Data []DataItem `json:"data"`
}

// AddSite adds a site to be managed by Incapsula
func (c *Client) AddSite(domain, refID, sendSiteSetupEmails, siteIP, forceSSL string, accountID int, nakedDomainSan bool, wildcarSan bool, logsAccountId string) (*SiteAddResponse, error) {
log.Printf("[INFO] Adding Incapsula site for domain: %s (account ID %d)\n", domain, accountID)
Expand Down Expand Up @@ -331,6 +347,42 @@ func (c *Client) UpdateSite(siteID, param, value string) (*SiteUpdateResponse, e

// Look at the response status code from Incapsula
if siteUpdateResponse.Res != 0 {
if siteUpdateResponse.Res == 1 && param == "domain_validation" { // Domain Validation parameter can throw code 1 when reusing wildcard certificate
//Get request for SSL certificate check on site
reqURL := fmt.Sprintf("%s/%s", c.config.BaseURLAPI, endpointCertDetails)
queryParams := url.Values{}
queryParams.Add("extSiteId", siteID)

resp, err := c.GetWithHeaders(reqURL, queryParams, UpdateSite)

if err != nil {
return nil, fmt.Errorf("Error checking certificate on site_id: %s: %s", siteID, err)
}

// Read the body
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)

// Dump JSON
log.Printf("[DEBUG] Incapsula check certificate JSON response: %s\n", string(responseBody))

// Parse the JSON
var response Response
err = json.Unmarshal([]byte(responseBody), &response)
if err != nil {
return nil, fmt.Errorf("Error parsing check certificate JSON response for siteID %s: %s", siteID, err)
}

// Check all SANs to verify if there's an active certificate already
for _, dataItem := range response.Data {
for _, san := range dataItem.Sans {
if san.Status != "PENDING_USER_ACTION" {
// There's an active certificate, avoiding internal error
return &siteUpdateResponse, nil
}
}
}
}
return nil, fmt.Errorf("Error from Incapsula service when updating site for siteID %s: %s", siteID, string(responseBody))
}

Expand Down

0 comments on commit fbbcca3

Please sign in to comment.