Skip to content

Commit

Permalink
add inext_web_user_response, tests and CI improvements (#9)
Browse files Browse the repository at this point in the history
* add inext_web_user_response, tests and CI improvements
  • Loading branch information
chkp-omris authored Jun 30, 2022
1 parent f959836 commit 1d2d852
Show file tree
Hide file tree
Showing 78 changed files with 925 additions and 366 deletions.
2 changes: 1 addition & 1 deletion docs/resources/inext_exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ resource "inext_exceptions" "my-exceptions-behavior" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/inext_log_trigger.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ resource "inext_log_trigger" "mytrigger" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/inext_trusted_sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ resource "inext_trusted_sources" "my-trusted-source-behavior" {
### Required

- `min_num_of_sources` (Number) Minimum number of users or addresses that must exhibit similar activity for the behavior to be considered benign
- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/inext_web_api_asset.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ resource "inext_web_api_asset" "my-webapi-asset" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID
- `urls` (Set of String) The application URLs

### Optional
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/inext_web_api_practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ resource "inext_web_api_practice" "my-webapi-practice" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

Expand Down
4 changes: 2 additions & 2 deletions docs/resources/inext_web_app_asset.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ resource "inext_web_app_asset" "my-webapp-asset" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID
- `urls` (Set of String) The application URLs

### Optional
Expand Down Expand Up @@ -95,11 +95,11 @@ resource "inext_web_app_asset" "my-webapp-asset" {
Required:

- `id` (String) The ID of this resource.
- `main_mode` (String) The mode of the practice: Prevent, Inactive, Disabled or Learn

Optional:

- `exceptions` (Set of String) The exceptions used with the practice
- `main_mode` (String) The mode of the practice: Prevent, Inactive, Disabled or Learn
- `sub_practices_modes` (Map of String) The name of the sub practice as the key and its mode as the value. Allowed modes: Detect, Prevent, Inactive, AccordingToPractice, Disabled, Learn or Active
- `triggers` (Set of String) The triggers used with the practice

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/inext_web_app_practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ resource "inext_web_app_practice" "my-webapp-practice" {

### Required

- `name` (String) The name of the resource, also acts as it's unique ID
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

Expand Down
58 changes: 58 additions & 0 deletions docs/resources/inext_web_user_response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "inext_web_user_response Resource - terraform-provider-infinity-next"
subcategory: ""
description: |-
Determine the response returned to the client who initiated a blocked traffic.The response can be a simple HTTP error code, an HTTP redirect message, or a Block page that a user can view in their browser.
---

# inext_web_user_response (Resource)

Determine the response returned to the client who initiated a blocked traffic.The response can be a simple HTTP error code, an HTTP redirect message, or a Block page that a user can view in their browser.

## Example Usage

```terraform
resource "inext_web_user_response" "web-user-response-blockpage" {
name = "web-user-response"
mode = "BlockPage"
http_response_code = 403
message_title = "some message title"
message_body = "some message body"
}
resource "inext_web_user_response" "web-user-response-redirect" {
name = "web-user-response-redirect"
mode = "Redirect"
redirect_url = "http://localhost:1234/test"
x_event_id = true
}
resource "inext_web_user_response" "web-user-response-responsecodeonly" {
name = "web-user-response-responsecodeonly"
mode = "ResponseCodeOnly"
http_response_code = 403
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `mode` (String) The type of the web user response object
- `name` (String) The name of the resource, also acts as its unique ID

### Optional

- `http_response_code` (Number) It is recommended to use a 403 (Forbidden) as a response code
- `message_body` (String) The body of the message to be shown to the user
- `message_title` (String) The title of the web page to be shown to the user sending the malicious traffic
- `redirect_url` (String) The client will be redirected to the provided URL where you can provide any customized web page
- `x_event_id` (Boolean) When selected the redirect message will include this header with a value that provides an internal reference ID that will match a security log generated by the incident, if log triggers are configured

### Read-Only

- `id` (String) The ID of this resource.


20 changes: 20 additions & 0 deletions examples/resources/inext_web_user_response/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "inext_web_user_response" "web-user-response-blockpage" {
name = "web-user-response"
mode = "BlockPage"
http_response_code = 403
message_title = "some message title"
message_body = "some message body"
}

resource "inext_web_user_response" "web-user-response-redirect" {
name = "web-user-response-redirect"
mode = "Redirect"
redirect_url = "http://localhost:1234/test"
x_event_id = true
}

resource "inext_web_user_response" "web-user-response-responsecodeonly" {
name = "web-user-response-responsecodeonly"
mode = "ResponseCodeOnly"
http_response_code = 403
}
4 changes: 3 additions & 1 deletion internal/acctest/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/CheckPointSW/terraform-provider-infinity-next/internal/api"
"github.com/CheckPointSW/terraform-provider-infinity-next/internal/utils"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -44,7 +45,8 @@ func CheckResourceDestroyed(resourcesNames []string) resource.TestCheckFunc {
if rs, ok := s.RootModule().Resources[resourceName]; ok {
rd := schema.ResourceData{}
rd.SetId(rs.Primary.ID)
diags := Provider.ResourcesMap[resourceType].ReadContext(context.Background(), &rd, Provider.Meta())
ctx := context.WithValue(context.Background(), utils.ExpectResourceNotFound, true)
diags := Provider.ResourcesMap[resourceType].ReadContext(ctx, &rd, Provider.Meta())
if diags.HasError() {
for _, d := range diags {
if !strings.Contains(d.Summary, api.ErrorNotFound.Error()) {
Expand Down
100 changes: 67 additions & 33 deletions internal/api/infinity_next_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package api

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"

"github.com/CheckPointSW/terraform-provider-infinity-next/internal/utils"
)

type GraphQLRequest struct {
Expand Down Expand Up @@ -49,40 +52,67 @@ func (c *Client) InfinityPortalAuthentication(clientId string, accessKey string)
"accessKey": {accessKey},
}

resp, err := client.PostForm(c.host+"/auth/external", formData)
if err != nil {
return err
}
for retryCount := 1; retryCount <= maxNumOfRetries; retryCount++ {
resp, err := client.PostForm(c.host+"/auth/external", formData)
if err != nil {
if retryCount == maxNumOfRetries {
return err
}

defer resp.Body.Close()
time.Sleep(2 * time.Second * time.Duration(retryCount))
continue
}

var result map[string]any
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return err
}
defer resp.Body.Close()

data, err := json.Marshal(result["data"])
if err != nil {
return err
}
var result map[string]any
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
if retryCount == maxNumOfRetries {
return err
}

jsonStr := string(data)
var datamap map[string]any
if err := json.Unmarshal([]byte(jsonStr), &datamap); err != nil {
return err
}
time.Sleep(2 * time.Second * time.Duration(retryCount))
continue
}

tokenInterface, ok := datamap["token"]
if !ok {
return fmt.Errorf("missing token in response %#v", result)
}
data, err := json.Marshal(result["data"])
if err != nil {
if retryCount == maxNumOfRetries {
return err
}

c.token = tokenInterface.(string)
time.Sleep(2 * time.Second * time.Duration(retryCount))
continue
}

jsonStr := string(data)
var datamap map[string]any
if err := json.Unmarshal([]byte(jsonStr), &datamap); err != nil {
if retryCount == maxNumOfRetries {
return err
}

time.Sleep(2 * time.Second * time.Duration(retryCount))
continue
}

tokenInterface, ok := datamap["token"]
if !ok {
if retryCount == maxNumOfRetries {
return fmt.Errorf("missing token in response %#v", result)
}

time.Sleep(2 * time.Second * time.Duration(retryCount))
continue
}

c.token = tokenInterface.(string)
}

return nil
}

func (c *Client) MakeGraphQLRequest(gql, responseKey string, vars ...map[string]any) (any, error) {
func (c *Client) MakeGraphQLRequest(ctx context.Context, gql, responseKey string, vars ...map[string]any) (any, error) {
variables := make(map[string]any)
for _, varMap := range vars {
for k, v := range varMap {
Expand Down Expand Up @@ -175,15 +205,19 @@ func (c *Client) MakeGraphQLRequest(gql, responseKey string, vars ...map[string]
}

if ret == nil {
err := fmt.Errorf("%s - ReferenceID: %s", ErrorNotFound.Error(), getReferenceIDFromHeaders(res.Header))
if retryCount == maxNumOfRetries {
return nil, err
// We need to retry only if it's expected to find the resource
// This is only used for test, because we ensure a resource is destroyed after a test using Read.
if v := ctx.Value(utils.ExpectResourceNotFound); v != nil && !v.(bool) {
err := fmt.Errorf("%s - ReferenceID: %s", ErrorNotFound.Error(), getReferenceIDFromHeaders(res.Header))
if retryCount == maxNumOfRetries {
return nil, err
}

res.Body.Close()
fmt.Printf("[WARN] GraphQL request failed with error %v, retrying...\n", err)
time.Sleep(time.Second * 2 * time.Duration(retryCount))
continue
}

res.Body.Close()
fmt.Printf("[WARN] GraphQL request failed with error %v, retrying...\n", err)
time.Sleep(time.Second * 2 * time.Duration(retryCount))
continue
}

return ret, nil
Expand Down Expand Up @@ -249,7 +283,7 @@ func (c *Client) PublishChanges() (bool, error) {
}

func (c *Client) DiscardChanges() (bool, error) {
discardChanges, err := c.MakeGraphQLRequest(`
discardChanges, err := c.MakeGraphQLRequest(context.Background(), `
mutation discardChanges{
discardChanges
}`, "discardChanges")
Expand Down
12 changes: 12 additions & 0 deletions internal/models/web-user-response/behavior.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package models

type WebUserResponseBehavior struct {
ID string `json:"id"`
Name string `json:"name"`
Mode string `json:"mode"`
MessageTitle string `json:"messageTitle"`
MessageBody string `json:"messageBody"`
HTTPResponseCode int `json:"httpResponseCode"`
RedirectURL string `json:"redirectURL"`
XEventID bool `json:"xEventId"`
}
12 changes: 12 additions & 0 deletions internal/models/web-user-response/input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package models

type CreateWebUserResponseBehaviorInput struct {
Name string `json:"name"`
Visibility string `json:"visibility"`
Mode string `json:"mode"`
MessageTitle string `json:"messageTitle"`
MessageBody string `json:"messageBody"`
HTTPResponseCode int `json:"httpResponseCode"`
RedirectURL string `json:"redirectURL"`
XEventID bool `json:"xEventId"`
}
11 changes: 11 additions & 0 deletions internal/models/web-user-response/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

type UpdateWebUserResponseBehaviorInput struct {
Name string `json:"name"`
Mode string `json:"mode"`
MessageTitle string `json:"messageTitle,omitempty"`
MessageBody string `json:"messageBody,omitempty"`
HTTPResponseCode int `json:"httpResponseCode,omitempty"`
RedirectURL string `json:"redirectURL,omitempty"`
XEventID bool `json:"xEventId"`
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func Provider() *schema.Provider {
"inext_trusted_sources": resources.ResourceTrustedSources(),
"inext_exceptions": resources.ResourceExceptions(),
"inext_access_token": resources.ResourceAccessToken(),
"inext_web_user_response": resources.ResourceWebUserResponse(),
},
ConfigureContextFunc: providerConfigure,
}
Expand Down
Loading

0 comments on commit 1d2d852

Please sign in to comment.