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 }