github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/appsec/custom_deny.go (about)

     1  package appsec
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"reflect"
     9  	"strconv"
    10  
    11  	validation "github.com/go-ozzo/ozzo-validation/v4"
    12  )
    13  
    14  type (
    15  	// The CustomDeny interface supports creating, retrievinfg, modifying and removing custom deny actions
    16  	// for a configuration.
    17  	CustomDeny interface {
    18  		// GetCustomDenyList returns custom deny actions for a specific security configuration version.
    19  		//
    20  		// See: https://techdocs.akamai.com/application-security/reference/get-custom-deny-actions
    21  		GetCustomDenyList(ctx context.Context, params GetCustomDenyListRequest) (*GetCustomDenyListResponse, error)
    22  
    23  		// GetCustomDeny returns the specified custom deny action.
    24  		//
    25  		// See: https://techdocs.akamai.com/application-security/reference/get-custom-deny-action
    26  		GetCustomDeny(ctx context.Context, params GetCustomDenyRequest) (*GetCustomDenyResponse, error)
    27  
    28  		// CreateCustomDeny creates a new custom deny action for a specific configuration version.
    29  		//
    30  		// See: https://techdocs.akamai.com/application-security/reference/post-custom-deny
    31  		CreateCustomDeny(ctx context.Context, params CreateCustomDenyRequest) (*CreateCustomDenyResponse, error)
    32  
    33  		// UpdateCustomDeny updates details for a specific custom deny action.
    34  		//
    35  		// See: https://techdocs.akamai.com/application-security/reference/put-custom-deny
    36  		UpdateCustomDeny(ctx context.Context, params UpdateCustomDenyRequest) (*UpdateCustomDenyResponse, error)
    37  
    38  		// RemoveCustomDeny deletes a custom deny action.
    39  		//
    40  		// See: https://techdocs.akamai.com/application-security/reference/delete-custom-deny
    41  		RemoveCustomDeny(ctx context.Context, params RemoveCustomDenyRequest) (*RemoveCustomDenyResponse, error)
    42  	}
    43  
    44  	customDenyID string
    45  
    46  	// GetCustomDenyListRequest is used to retrieve the custom deny actions for a configuration.
    47  	GetCustomDenyListRequest struct {
    48  		ConfigID int    `json:"configId"`
    49  		Version  int    `json:"version"`
    50  		ID       string `json:"id,omitempty"`
    51  	}
    52  
    53  	// GetCustomDenyListResponse is returned from a call to GetCustomDenyList.
    54  	GetCustomDenyListResponse struct {
    55  		CustomDenyList []struct {
    56  			Description string       `json:"description,omitempty"`
    57  			Name        string       `json:"name"`
    58  			ID          customDenyID `json:"id"`
    59  			Parameters  []struct {
    60  				DisplayName string `json:"-"`
    61  				Name        string `json:"name"`
    62  				Value       string `json:"value"`
    63  			} `json:"parameters"`
    64  		} `json:"customDenyList"`
    65  	}
    66  
    67  	// GetCustomDenyRequest is used to retrieve a specific custom deny action.
    68  	GetCustomDenyRequest struct {
    69  		ConfigID int    `json:"configId"`
    70  		Version  int    `json:"version"`
    71  		ID       string `json:"id,omitempty"`
    72  	}
    73  
    74  	// GetCustomDenyResponse is returned from a call to GetCustomDeny.
    75  	GetCustomDenyResponse struct {
    76  		Description string       `json:"description,omitempty"`
    77  		Name        string       `json:"name"`
    78  		ID          customDenyID `json:"-"`
    79  		Parameters  []struct {
    80  			DisplayName string `json:"-"`
    81  			Name        string `json:"name"`
    82  			Value       string `json:"value"`
    83  		} `json:"parameters"`
    84  	}
    85  
    86  	// CreateCustomDenyRequest is used to create a new custom deny action for a specific configuration.
    87  	CreateCustomDenyRequest struct {
    88  		ConfigID       int             `json:"-"`
    89  		Version        int             `json:"-"`
    90  		JsonPayloadRaw json.RawMessage `json:"-"`
    91  	}
    92  
    93  	// CreateCustomDenyResponse is returned from a call to CreateCustomDeny.
    94  	CreateCustomDenyResponse struct {
    95  		Description string       `json:"description,omitempty"`
    96  		Name        string       `json:"name"`
    97  		ID          customDenyID `json:"id"`
    98  		Parameters  []struct {
    99  			DisplayName string `json:"-"`
   100  			Name        string `json:"name"`
   101  			Value       string `json:"value"`
   102  		} `json:"parameters"`
   103  	}
   104  
   105  	// UpdateCustomDenyRequest is used to details for a specific custom deny action.
   106  	UpdateCustomDenyRequest struct {
   107  		ConfigID       int             `json:"-"`
   108  		Version        int             `json:"-"`
   109  		ID             string          `json:"id"`
   110  		JsonPayloadRaw json.RawMessage `json:"-"`
   111  	}
   112  
   113  	// UpdateCustomDenyResponse is returned from a call to UpdateCustomDeny.
   114  	UpdateCustomDenyResponse struct {
   115  		Description string       `json:"description,omitempty"`
   116  		Name        string       `json:"name"`
   117  		ID          customDenyID `json:"-"`
   118  		Parameters  []struct {
   119  			DisplayName string `json:"-"`
   120  			Name        string `json:"name"`
   121  			Value       string `json:"value"`
   122  		} `json:"parameters"`
   123  	}
   124  
   125  	// RemoveCustomDenyRequest is used to remove an existing custom deny action.
   126  	RemoveCustomDenyRequest struct {
   127  		ConfigID int    `json:"-"`
   128  		Version  int    `json:"-"`
   129  		ID       string `json:"id,omitempty"`
   130  	}
   131  
   132  	// RemoveCustomDenyResponse is returned from a call to RemoveCustomDeny.
   133  	RemoveCustomDenyResponse struct {
   134  		Empty string `json:"-"`
   135  	}
   136  )
   137  
   138  // UnmarshalJSON reads a customDenyID struct from its data argument.
   139  func (c *customDenyID) UnmarshalJSON(data []byte) error {
   140  	var nums interface{}
   141  	err := json.Unmarshal(data, &nums)
   142  	if err != nil {
   143  		return err
   144  	}
   145  
   146  	items := reflect.ValueOf(nums)
   147  	switch items.Kind() {
   148  	case reflect.String:
   149  		*c = customDenyID(nums.(string))
   150  	case reflect.Int:
   151  
   152  		*c = customDenyID(strconv.Itoa(nums.(int)))
   153  
   154  	}
   155  	return nil
   156  }
   157  
   158  // Validate validates a GetCustomDenyRequest.
   159  func (v GetCustomDenyRequest) Validate() error {
   160  	return validation.Errors{
   161  		"ConfigID": validation.Validate(v.ConfigID, validation.Required),
   162  		"Version":  validation.Validate(v.Version, validation.Required),
   163  		"ID":       validation.Validate(v.ID, validation.Required),
   164  	}.Filter()
   165  }
   166  
   167  // Validate validates a GetCustomDenysRequest.
   168  func (v GetCustomDenyListRequest) Validate() error {
   169  	return validation.Errors{
   170  		"ConfigID": validation.Validate(v.ConfigID, validation.Required),
   171  		"Version":  validation.Validate(v.Version, validation.Required),
   172  	}.Filter()
   173  }
   174  
   175  // Validate validates a CreateCustomDenyRequest.
   176  func (v CreateCustomDenyRequest) Validate() error {
   177  	return validation.Errors{
   178  		"ConfigID": validation.Validate(v.ConfigID, validation.Required),
   179  		"Version":  validation.Validate(v.Version, validation.Required),
   180  	}.Filter()
   181  }
   182  
   183  // Validate validates an UpdateCustomDenyRequest.
   184  func (v UpdateCustomDenyRequest) Validate() error {
   185  	return validation.Errors{
   186  		"ConfigID": validation.Validate(v.ConfigID, validation.Required),
   187  		"Version":  validation.Validate(v.Version, validation.Required),
   188  		"ID":       validation.Validate(v.ID, validation.Required),
   189  	}.Filter()
   190  }
   191  
   192  // Validate validates a RemoveCustomDenyRequest.
   193  func (v RemoveCustomDenyRequest) Validate() error {
   194  	return validation.Errors{
   195  		"ConfigID": validation.Validate(v.ConfigID, validation.Required),
   196  		"Version":  validation.Validate(v.Version, validation.Required),
   197  		"ID":       validation.Validate(v.ID, validation.Required),
   198  	}.Filter()
   199  }
   200  
   201  func (p *appsec) GetCustomDeny(ctx context.Context, params GetCustomDenyRequest) (*GetCustomDenyResponse, error) {
   202  	logger := p.Log(ctx)
   203  	logger.Debug("GetCustomDeny")
   204  
   205  	if err := params.Validate(); err != nil {
   206  		return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error())
   207  	}
   208  
   209  	uri := fmt.Sprintf(
   210  		"/appsec/v1/configs/%d/versions/%d/custom-deny/%s",
   211  		params.ConfigID,
   212  		params.Version,
   213  		params.ID)
   214  
   215  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
   216  	if err != nil {
   217  		return nil, fmt.Errorf("failed to create GetCustomDeny request: %w", err)
   218  	}
   219  
   220  	var result GetCustomDenyResponse
   221  	resp, err := p.Exec(req, &result)
   222  	if err != nil {
   223  		return nil, fmt.Errorf("get custom deny request failed: %w", err)
   224  	}
   225  	if resp.StatusCode != http.StatusOK {
   226  		return nil, p.Error(resp)
   227  	}
   228  
   229  	return &result, nil
   230  }
   231  
   232  func (p *appsec) GetCustomDenyList(ctx context.Context, params GetCustomDenyListRequest) (*GetCustomDenyListResponse, error) {
   233  	logger := p.Log(ctx)
   234  	logger.Debug("GetCustomDenyList")
   235  
   236  	if err := params.Validate(); err != nil {
   237  		return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error())
   238  	}
   239  
   240  	uri := fmt.Sprintf(
   241  		"/appsec/v1/configs/%d/versions/%d/custom-deny",
   242  		params.ConfigID,
   243  		params.Version,
   244  	)
   245  
   246  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
   247  	if err != nil {
   248  		return nil, fmt.Errorf("failed to create GetCustomDenyList request: %w", err)
   249  	}
   250  
   251  	var result GetCustomDenyListResponse
   252  	resp, err := p.Exec(req, &result)
   253  	if err != nil {
   254  		return nil, fmt.Errorf("get custom deny list request failed: %w", err)
   255  	}
   256  	if resp.StatusCode != http.StatusOK {
   257  		return nil, p.Error(resp)
   258  	}
   259  
   260  	if params.ID != "" {
   261  		var filteredResult GetCustomDenyListResponse
   262  		for _, val := range result.CustomDenyList {
   263  			if string(val.ID) == params.ID {
   264  				filteredResult.CustomDenyList = append(filteredResult.CustomDenyList, val)
   265  			}
   266  		}
   267  		return &filteredResult, nil
   268  	}
   269  
   270  	return &result, nil
   271  }
   272  
   273  func (p *appsec) UpdateCustomDeny(ctx context.Context, params UpdateCustomDenyRequest) (*UpdateCustomDenyResponse, error) {
   274  	logger := p.Log(ctx)
   275  	logger.Debug("UpdateCustomDeny")
   276  
   277  	if err := params.Validate(); err != nil {
   278  		return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error())
   279  	}
   280  
   281  	uri := fmt.Sprintf(
   282  		"/appsec/v1/configs/%d/versions/%d/custom-deny/%s",
   283  		params.ConfigID,
   284  		params.Version,
   285  		params.ID,
   286  	)
   287  
   288  	req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri, nil)
   289  	if err != nil {
   290  		return nil, fmt.Errorf("failed to create UpdateCustomDeny request: %w", err)
   291  	}
   292  
   293  	var result UpdateCustomDenyResponse
   294  	req.Header.Set("Content-Type", "application/json")
   295  	resp, err := p.Exec(req, &result, params.JsonPayloadRaw)
   296  	if err != nil {
   297  		return nil, fmt.Errorf("update custom deny request failed: %w", err)
   298  	}
   299  	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
   300  		return nil, p.Error(resp)
   301  	}
   302  
   303  	return &result, nil
   304  }
   305  
   306  func (p *appsec) CreateCustomDeny(ctx context.Context, params CreateCustomDenyRequest) (*CreateCustomDenyResponse, error) {
   307  	logger := p.Log(ctx)
   308  	logger.Debug("CreateCustomDeny")
   309  
   310  	if err := params.Validate(); err != nil {
   311  		return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error())
   312  	}
   313  
   314  	uri := fmt.Sprintf(
   315  		"/appsec/v1/configs/%d/versions/%d/custom-deny",
   316  		params.ConfigID,
   317  		params.Version,
   318  	)
   319  
   320  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil)
   321  	if err != nil {
   322  		return nil, fmt.Errorf("failed to create CreateCustomDeny request: %w", err)
   323  	}
   324  
   325  	var result CreateCustomDenyResponse
   326  	req.Header.Set("Content-Type", "application/json")
   327  	resp, err := p.Exec(req, &result, params.JsonPayloadRaw)
   328  	if err != nil {
   329  		return nil, fmt.Errorf("create custom deny request failed: %w", err)
   330  	}
   331  	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
   332  		return nil, p.Error(resp)
   333  	}
   334  
   335  	return &result, nil
   336  }
   337  
   338  func (p *appsec) RemoveCustomDeny(ctx context.Context, params RemoveCustomDenyRequest) (*RemoveCustomDenyResponse, error) {
   339  	logger := p.Log(ctx)
   340  	logger.Debug("RemoveCustomDeny")
   341  
   342  	if err := params.Validate(); err != nil {
   343  		return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error())
   344  	}
   345  
   346  	uri := fmt.Sprintf("/appsec/v1/configs/%d/versions/%d/custom-deny/%s", params.ConfigID, params.Version, params.ID)
   347  	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
   348  	if err != nil {
   349  		return nil, fmt.Errorf("failed to create RemoveCustomDeny request: %w", err)
   350  	}
   351  
   352  	var result RemoveCustomDenyResponse
   353  	resp, err := p.Exec(req, &result)
   354  	if err != nil {
   355  		return nil, fmt.Errorf("remove custom deny request failed: %w", err)
   356  	}
   357  	if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
   358  		return nil, p.Error(resp)
   359  	}
   360  
   361  	return &result, nil
   362  }