From bd026333788897b5aa8496000d759fdf50593311 Mon Sep 17 00:00:00 2001 From: Michal Wojcik Date: Thu, 31 Mar 2022 20:37:24 +0000 Subject: [PATCH 1/8] DXE-822 PointShapeType contains field `True` instead of `Y` --- pkg/imaging/policy.gen.go | 8 +++-- pkg/imaging/policy_test.go | 65 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/pkg/imaging/policy.gen.go b/pkg/imaging/policy.gen.go index 0c944e8a..8805eb45 100644 --- a/pkg/imaging/policy.gen.go +++ b/pkg/imaging/policy.gen.go @@ -579,10 +579,10 @@ type ( // PointShapeType Defines coordinates for a single point, to help define polygons and rectangles. Each point may be an object with `x`and `y` members, or a two-element array. PointShapeType struct { - // True The vertical position of the point, measured in pixels. - True *NumberVariableInline `json:"true,omitempty"` // X The horizontal position of the point, measured in pixels. X *NumberVariableInline `json:"x"` + // Y The vertical position of the point, measured in pixels. + Y *NumberVariableInline `json:"y"` } // PolicyOutputImage Specifies details for each policy, such as transformations to apply and variations in image size and formats. @@ -2222,10 +2222,12 @@ func (o OutputImagePerceptualQualityVariableInline) Validate() error { // Validate validates PointShapeType func (p PointShapeType) Validate() error { return validation.Errors{ - "True": validation.Validate(p.True), "X": validation.Validate(p.X, validation.Required, ), + "Y": validation.Validate(p.Y, + validation.Required, + ), }.Filter() } diff --git a/pkg/imaging/policy_test.go b/pkg/imaging/policy_test.go index 318dc95d..26824cc5 100644 --- a/pkg/imaging/policy_test.go +++ b/pkg/imaging/policy_test.go @@ -1190,6 +1190,39 @@ func TestGetPolicy(t *testing.T) { "perceptualQuality": "mediumHigh" }, "transformations": [ + { + "transformation": "Append", + "gravity": "Center", + "gravityPriority": "horizontal", + "preserveMinorDimension": true, + "image": { + "type": "Text", + "fill": "#000000", + "size": 72, + "stroke": "#FFFFFF", + "strokeSize": 0, + "text": "test", + "transformation": { + "transformation": "Compound", + "transformations": [] + } + } + }, + { + "transformation": "RegionOfInterestCrop", + "style": "fill", + "gravity": "Center", + "width": 7, + "height": 8, + "regionOfInterest": { + "anchor": { + "x": 4, + "y": 5 + }, + "width": 8, + "height": 9 + } + }, { "transformation": "Composite", "xPosition": 0, @@ -1237,6 +1270,38 @@ func TestGetPolicy(t *testing.T) { }, }, Transformations: []TransformationType{ + &Append{ + Transformation: "Append", + Gravity: &GravityVariableInline{Value: GravityPtr("Center")}, + GravityPriority: &AppendGravityPriorityVariableInline{Value: AppendGravityPriorityPtr("horizontal")}, + PreserveMinorDimension: &BooleanVariableInline{Value: tools.BoolPtr(true)}, + Image: &TextImageType{ + Type: "Text", + Fill: &StringVariableInline{Value: tools.StringPtr("#000000")}, + Size: &NumberVariableInline{Value: tools.Float32Ptr(72)}, + Stroke: &StringVariableInline{Value: tools.StringPtr("#FFFFFF")}, + StrokeSize: &NumberVariableInline{Value: tools.Float32Ptr(0)}, + Text: &StringVariableInline{Value: tools.StringPtr("test")}, + Transformation: &Compound{ + Transformation: "Compound", + }, + }, + }, + &RegionOfInterestCrop{ + Transformation: "RegionOfInterestCrop", + Style: &RegionOfInterestCropStyleVariableInline{Value: RegionOfInterestCropStylePtr("fill")}, + Gravity: &GravityVariableInline{Value: GravityPtr("Center")}, + Width: &IntegerVariableInline{Value: tools.IntPtr(7)}, + Height: &IntegerVariableInline{Value: tools.IntPtr(8)}, + RegionOfInterest: &RectangleShapeType{ + Anchor: PointShapeType{ + X: &NumberVariableInline{Value: tools.Float32Ptr(4)}, + Y: &NumberVariableInline{Value: tools.Float32Ptr(5)}, + }, + Width: &NumberVariableInline{Value: tools.Float32Ptr(8)}, + Height: &NumberVariableInline{Value: tools.Float32Ptr(9)}, + }, + }, &Composite{ Transformation: "Composite", XPosition: &IntegerVariableInline{ From b66fc8e8a6add3d0e758d4ac5750c6ff8f6317c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=B3pez=20L=C3=B3pez=2C=20Roberto?= Date: Fri, 8 Apr 2022 13:32:58 +0200 Subject: [PATCH 2/8] DXE-819 make dates int64 to avoid overflow in 32-bit systems --- pkg/cloudlets/policy_version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cloudlets/policy_version.go b/pkg/cloudlets/policy_version.go index 2071fabf..45bb8ee5 100644 --- a/pkg/cloudlets/policy_version.go +++ b/pkg/cloudlets/policy_version.go @@ -50,9 +50,9 @@ type ( Version int64 `json:"version"` Description string `json:"description"` CreatedBy string `json:"createdBy"` - CreateDate int `json:"createDate"` + CreateDate int64 `json:"createDate"` LastModifiedBy string `json:"lastModifiedBy"` - LastModifiedDate int `json:"lastModifiedDate"` + LastModifiedDate int64 `json:"lastModifiedDate"` RulesLocked bool `json:"rulesLocked"` Activations []PolicyActivation `json:"activations"` MatchRules MatchRules `json:"matchRules"` From 5ac0d4ce1067e87baa0676d23f49ae2bd03faedf Mon Sep 17 00:00:00 2001 From: Tatiana Slonimskaia Date: Fri, 15 Apr 2022 14:15:49 +0000 Subject: [PATCH 3/8] DXE-824 Updated Godoc links for edgeKV Merge in DEVEXP/akamaiopen-edgegrid-golang from feature/DXE-824-update-links-for-edgekv-endpoints-in-edgegrid to v2 --- pkg/edgeworkers/edgekv_access_tokens.go | 8 ++++---- pkg/edgeworkers/edgekv_initialize.go | 4 ++-- pkg/edgeworkers/edgekv_items.go | 8 ++++---- pkg/edgeworkers/edgekv_namespaces.go | 11 +++++++---- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/pkg/edgeworkers/edgekv_access_tokens.go b/pkg/edgeworkers/edgekv_access_tokens.go index e46549a0..c9fbed50 100644 --- a/pkg/edgeworkers/edgekv_access_tokens.go +++ b/pkg/edgeworkers/edgekv_access_tokens.go @@ -16,22 +16,22 @@ type ( EdgeKVAccessTokens interface { // CreateEdgeKVAccessToken generates EdgeKV specific access token // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#6-generate-an-edgekv-access-token + // See: https://techdocs.akamai.com/edgekv/reference/post_tokens CreateEdgeKVAccessToken(context.Context, CreateEdgeKVAccessTokenRequest) (*CreateEdgeKVAccessTokenResponse, error) // GetEdgeKVAccessToken retrieves an EdgeKV access token // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#7-retrieve-an-edgekv-access-token + // See: https://techdocs.akamai.com/edgekv/reference/get_token GetEdgeKVAccessToken(context.Context, GetEdgeKVAccessTokenRequest) (*GetEdgeKVAccessTokenResponse, error) // ListEdgeKVAccessTokens lists EdgeKV access tokens // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#8-list-edgekv-access-tokens + // See: https://techdocs.akamai.com/edgekv/reference/get_tokens ListEdgeKVAccessTokens(context.Context, ListEdgeKVAccessTokensRequest) (*ListEdgeKVAccessTokensResponse, error) // DeleteEdgeKVAccessToken revokes an EdgeKV access token // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#9-revoke-an-edgekv-access-token + // See: https://techdocs.akamai.com/edgekv/reference/delete_token DeleteEdgeKVAccessToken(context.Context, DeleteEdgeKVAccessTokenRequest) (*DeleteEdgeKVAccessTokenResponse, error) } diff --git a/pkg/edgeworkers/edgekv_initialize.go b/pkg/edgeworkers/edgekv_initialize.go index c38437c1..f69501d2 100644 --- a/pkg/edgeworkers/edgekv_initialize.go +++ b/pkg/edgeworkers/edgekv_initialize.go @@ -12,12 +12,12 @@ type ( EdgeKVInitialize interface { // InitializeEdgeKV Initialize the EdgeKV database // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#1-initialize-edgekv-for-the-first-time + // See: https://techdocs.akamai.com/edgekv/reference/put_initialize InitializeEdgeKV(ctx context.Context) (*EdgeKVInitializationStatus, error) // GetEdgeKVInitializationStatus is used to check on the current initialization status // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#1-initialize-edgekv-for-the-first-time + // See: https://techdocs.akamai.com/edgekv/reference/get_initialize GetEdgeKVInitializationStatus(ctx context.Context) (*EdgeKVInitializationStatus, error) } diff --git a/pkg/edgeworkers/edgekv_items.go b/pkg/edgeworkers/edgekv_items.go index 5969b0f9..7dda9b56 100644 --- a/pkg/edgeworkers/edgekv_items.go +++ b/pkg/edgeworkers/edgekv_items.go @@ -17,22 +17,22 @@ type ( EdgeKVItems interface { // ListItems lists items in EdgeKV group // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#13--list-items-within-a-group + // See: https://techdocs.akamai.com/edgekv/reference/get_group ListItems(context.Context, ListItemsRequest) (*ListItemsResponse, error) // GetItem reads an item from EdgeKV group // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#11--read-an-item-from-an-edgekv-namespace + // See: https://techdocs.akamai.com/edgekv/reference/get_item GetItem(context.Context, GetItemRequest) (*Item, error) // UpsertItem creates or updates an item in EdgeKV group // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#10--write-an-item-to-an-edgekv-namespace + // See: https://techdocs.akamai.com/edgekv/reference/put_item UpsertItem(context.Context, UpsertItemRequest) (*string, error) // DeleteItem deletes an item from EdgeKV group // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#12--delete-an-item-from-an-edgekv-namespace + // See: https://techdocs.akamai.com/edgekv/reference/delete_item DeleteItem(context.Context, DeleteItemRequest) (*string, error) } diff --git a/pkg/edgeworkers/edgekv_namespaces.go b/pkg/edgeworkers/edgekv_namespaces.go index 6873bc09..53db1a63 100644 --- a/pkg/edgeworkers/edgekv_namespaces.go +++ b/pkg/edgeworkers/edgekv_namespaces.go @@ -15,19 +15,22 @@ type ( EdgeKVNamespaces interface { // ListEdgeKVNamespaces lists all namespaces in the given network // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#2--list-edgekv-namespaces + // See: https://techdocs.akamai.com/edgekv/reference/get_namespaces ListEdgeKVNamespaces(context.Context, ListEdgeKVNamespacesRequest) (*ListEdgeKVNamespacesResponse, error) + // GetEdgeKVNamespace fetches a namespace by name // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#4-read-edgekv-namespace-details + // See: https://techdocs.akamai.com/edgekv/reference/get_namespace GetEdgeKVNamespace(context.Context, GetEdgeKVNamespaceRequest) (*Namespace, error) + // CreateEdgeKVNamespace creates a namespace on the given network // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#3-create-an-edgekv-namespace + // See: https://techdocs.akamai.com/edgekv/reference/post_namespace CreateEdgeKVNamespace(context.Context, CreateEdgeKVNamespaceRequest) (*Namespace, error) + // UpdateEdgeKVNamespace updates a namespace // - // See: https://github.com/akamai/edgeworkers-examples/tree/master/edgekv/apis#5-update-an-edgekv-namespace + // See: https://techdocs.akamai.com/edgekv/reference/put_namespace UpdateEdgeKVNamespace(context.Context, UpdateEdgeKVNamespaceRequest) (*Namespace, error) } From 84a24fc9a4cbe34c5f118db06e925f694065c713 Mon Sep 17 00:00:00 2001 From: Roberto Lopez Lopez Date: Tue, 19 Apr 2022 13:26:10 +0000 Subject: [PATCH 4/8] DXE-807 add limitKey, limit, remaining to papi.Error --- pkg/papi/errors.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/papi/errors.go b/pkg/papi/errors.go index a7b95f29..9ee61da1 100644 --- a/pkg/papi/errors.go +++ b/pkg/papi/errors.go @@ -20,6 +20,9 @@ type ( StatusCode int `json:"statusCode,omitempty"` Errors json.RawMessage `json:"errors,omitempty"` Warnings json.RawMessage `json:"warnings,omitempty"` + LimitKey string `json:"limitKey"` + Limit int `json:"limit"` + Remaining int `json:"remaining"` } ) From a18379842f6d4bd9ae6d0095a61853702894acd4 Mon Sep 17 00:00:00 2001 From: Roberto Lopez Lopez Date: Fri, 1 Apr 2022 07:29:56 +0000 Subject: [PATCH 5/8] SECKSD-13372 Deprecate single policy WAP endpoints and update doc --- CHANGELOG.md | 6 + pkg/appsec/appsec.go | 1 + pkg/appsec/bypass_network_lists.go | 4 + pkg/appsec/eval_host.go | 6 +- pkg/appsec/eval_protect_host.go | 5 +- pkg/appsec/selected_hostname.go | 7 +- pkg/appsec/wap_bypass_network_lists.go | 220 ++++++++++++++++ pkg/appsec/wap_bypass_network_lists_test.go | 278 ++++++++++++++++++++ 8 files changed, 523 insertions(+), 4 deletions(-) create mode 100644 pkg/appsec/wap_bypass_network_lists.go create mode 100644 pkg/appsec/wap_bypass_network_lists_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 9caae65b..489ea033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # EDGEGRID GOLANG RELEASE NOTES +## 2.xx.x (Apr. xx, 2022) + +#### FEATURES/ENHANCEMENTS: +* APPSEC + * Add WAPBypassNetworkLists interface, to be used in preference to deprecated BypassNetworkLists interface. + ## 2.11.0 (March 24, 2022) #### FEATURES/ENHANCEMENTS: diff --git a/pkg/appsec/appsec.go b/pkg/appsec/appsec.go index dedd4987..50f3b7a1 100644 --- a/pkg/appsec/appsec.go +++ b/pkg/appsec/appsec.go @@ -72,6 +72,7 @@ type ( VersionNotes WAFMode WAFProtection + WAPBypassNetworkLists WAPSelectedHostnames } diff --git a/pkg/appsec/bypass_network_lists.go b/pkg/appsec/bypass_network_lists.go index f8f010fb..29887647 100644 --- a/pkg/appsec/bypass_network_lists.go +++ b/pkg/appsec/bypass_network_lists.go @@ -11,16 +11,20 @@ import ( type ( // The BypassNetworkLists interface supports listing or modifying which network lists are // used in the bypass network lists settings. + // Deprecated: this interface will be removed in a future release. Use the WAPBypassNetworkLists interface instead. // // https://developer.akamai.com/api/cloud_security/application_security/v1.html#bypassnetworklist BypassNetworkLists interface { + // Deprecated: this method will be removed in a future release. Use the GetWAPBypassNetworkLists method of the WAPBypassNetworkLists interface instead. // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getbypassnetworklistsforawapconfigversion GetBypassNetworkLists(ctx context.Context, params GetBypassNetworkListsRequest) (*GetBypassNetworkListsResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putbypassnetworklistsforawapconfigversion + // Deprecated: this method will be removed in a future release. Use the UpdateWAPBypassNetworkLists method of the WAPBypassNetworkLists interface instead. UpdateBypassNetworkLists(ctx context.Context, params UpdateBypassNetworkListsRequest) (*UpdateBypassNetworkListsResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putbypassnetworklistsforawapconfigversion + // Deprecated: this method will be removed in a future release. Use the UpdateWAPBypassNetworkLists method of the WAPBypassNetworkLists interface instead. RemoveBypassNetworkLists(ctx context.Context, params RemoveBypassNetworkListsRequest) (*RemoveBypassNetworkListsResponse, error) } diff --git a/pkg/appsec/eval_host.go b/pkg/appsec/eval_host.go index 64953831..be4512fa 100644 --- a/pkg/appsec/eval_host.go +++ b/pkg/appsec/eval_host.go @@ -10,20 +10,24 @@ import ( type ( // The EvalHost interface supports retrieving and modifying list of evaluation hostnames for a configuration. + // Deprecated: this interface will be removed in a future release. Use the WAPSelectedHostnames interface instead. // // https://developer.akamai.com/api/cloud_security/application_security/v1.html#evalhostname EvalHost interface { // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getevaluationhostnames + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetEvalHosts(ctx context.Context, params GetEvalHostsRequest) (*GetEvalHostsResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getevaluationhostnames - // Deprecated: this method will be removed in a future release. Use GetEvalHosts instead. + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetEvalHost(ctx context.Context, params GetEvalHostRequest) (*GetEvalHostResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putevaluationhostnames + // Deprecated: this method will be removed in a future release. Use the UpdateWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. UpdateEvalHost(ctx context.Context, params UpdateEvalHostRequest) (*UpdateEvalHostResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putevaluationhostnames + // Deprecated: this method will be removed in a future release. Use the WAPSelectedHostnames method of the WAPSelectedHostnames interface instead. RemoveEvalHost(ctx context.Context, params RemoveEvalHostRequest) (*RemoveEvalHostResponse, error) } diff --git a/pkg/appsec/eval_protect_host.go b/pkg/appsec/eval_protect_host.go index 9f7bdc45..0340d9e8 100644 --- a/pkg/appsec/eval_protect_host.go +++ b/pkg/appsec/eval_protect_host.go @@ -11,17 +11,20 @@ import ( type ( // The EvalProtectHost interface supports retrieving the evaluation hostnames for a configuration and // moving hostnames from evaluating to protected status. + // Deprecated: this interface will be removed in a future release. Use the WAPSelectedHostnames interface instead. // // https://developer.akamai.com/api/cloud_security/application_security/v1.html#evalhostname EvalProtectHost interface { // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getevaluationhostnames + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetEvalProtectHosts(ctx context.Context, params GetEvalProtectHostsRequest) (*GetEvalProtectHostsResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getevaluationhostnames - // Deprecated: this method will be removed in a future release. Use GetEvalProtectHosts instead. + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetEvalProtectHost(ctx context.Context, params GetEvalProtectHostRequest) (*GetEvalProtectHostResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putmoveevaluationhostnamestoprotection + // Deprecated: this method will be removed in a future release. Use the UpdateWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. UpdateEvalProtectHost(ctx context.Context, params UpdateEvalProtectHostRequest) (*UpdateEvalProtectHostResponse, error) } diff --git a/pkg/appsec/selected_hostname.go b/pkg/appsec/selected_hostname.go index 8db70b96..bc0d1c2c 100644 --- a/pkg/appsec/selected_hostname.go +++ b/pkg/appsec/selected_hostname.go @@ -13,19 +13,22 @@ type ( // a configuration. // // https://developer.akamai.com/api/cloud_security/application_security/v1.html#selectedhostnames + // Deprecated: this interface will be removed in a future release. Use the WAPSelectedHostnames interface instead. SelectedHostname interface { // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getselectedhostnames + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetSelectedHostnames(ctx context.Context, params GetSelectedHostnamesRequest) (*GetSelectedHostnamesResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getselectedhostnames - // Deprecated: this method will be removed in a future release. Use GetSelectedHostnames instead. + // Deprecated: this method will be removed in a future release. Use the GetWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. GetSelectedHostname(ctx context.Context, params GetSelectedHostnameRequest) (*GetSelectedHostnameResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putselectedhostnames - // Deprecated: this method will be removed in a future release. Use UpdateSelectedHostnames instead. + // Deprecated: this method will be removed in a future release. Use the UpdateWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. UpdateSelectedHostname(ctx context.Context, params UpdateSelectedHostnameRequest) (*UpdateSelectedHostnameResponse, error) // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putselectedhostnames + // Deprecated: this method will be removed in a future release. Use the UpdateWAPSelectedHostnames method of the WAPSelectedHostnames interface instead. UpdateSelectedHostnames(ctx context.Context, params UpdateSelectedHostnamesRequest) (*UpdateSelectedHostnamesResponse, error) } diff --git a/pkg/appsec/wap_bypass_network_lists.go b/pkg/appsec/wap_bypass_network_lists.go new file mode 100644 index 00000000..64fb479a --- /dev/null +++ b/pkg/appsec/wap_bypass_network_lists.go @@ -0,0 +1,220 @@ +package appsec + +import ( + "context" + "fmt" + "net/http" + + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +type ( + // The WAPBypassNetworkLists interface supports listing or modifying which network lists are + // used in the bypass network lists settings. + // + // https://developer.akamai.com/api/cloud_security/application_security/v1.html#bypassnetworklist + WAPBypassNetworkLists interface { + // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getbypassnetworklistsforawapconfigversion + GetWAPBypassNetworkLists(ctx context.Context, params GetWAPBypassNetworkListsRequest) (*GetWAPBypassNetworkListsResponse, error) + + // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putbypassnetworklistsforawapconfigversion + UpdateWAPBypassNetworkLists(ctx context.Context, params UpdateWAPBypassNetworkListsRequest) (*UpdateWAPBypassNetworkListsResponse, error) + + // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putbypassnetworklistsforawapconfigversion + RemoveWAPBypassNetworkLists(ctx context.Context, params RemoveWAPBypassNetworkListsRequest) (*RemoveWAPBypassNetworkListsResponse, error) + } + + // GetWAPBypassNetworkListsRequest is used to list which network lists are used in the bypass network lists settings. + GetWAPBypassNetworkListsRequest struct { + ConfigID int `json:"-"` + Version int `json:"-"` + PolicyID string `json:"policyId"` + } + + // NetworkListsStruct is used to define a network list. + NetworkListsStruct struct { + Name string `json:"name"` + ID string `json:"id"` + } + + // GetWAPBypassNetworkListsResponse is returned from a call to GetWAPBypassNetworkLists. + GetWAPBypassNetworkListsResponse struct { + NetworkLists []NetworkListsStruct `json:"networkLists"` + } + + // UpdateWAPBypassNetworkListsRequest is used to modify which network lists are used in the bypass network lists settings. + UpdateWAPBypassNetworkListsRequest struct { + ConfigID int `json:"-"` + Version int `json:"-"` + PolicyID string `json:"policyId"` + NetworkLists []string `json:"networkLists"` + } + + // IPNetworkListsList is used to define a list of IP network lists. + IPNetworkListsList struct { + NetworkList []string `json:"networkList"` + } + + // GeoControlsList is used to define a list of blocked IP network lists. + GeoControlsList struct { + BlockedIPNetworkLists IPNetworkListsList `json:"networkList"` + } + + // IPControlsLists is used to define lists of allowed and blocked IP network lists. + IPControlsLists struct { + AllowedIPNetworkLists IPNetworkListsList `json:"allowedIPNetworkLists"` + BlockedIPNetworkLists IPNetworkListsList `json:"blockedIPNetworkLists"` + } + + // UpdateWAPBypassNetworkListsResponse is returned from a call to UpdateWAPBypassNetworkLists. + UpdateWAPBypassNetworkListsResponse struct { + Block string `json:"block"` + GeoControls GeoControlsList `json:"geoControls"` + IPControls IPControlsLists `json:"ipControls"` + } + + // RemoveWAPBypassNetworkListsRequest is used to modify which network lists are used in the bypass network lists settings. + // Deprecated: this struct will be removed in a future release. + RemoveWAPBypassNetworkListsRequest struct { + ConfigID int `json:"-"` + Version int `json:"-"` + PolicyID string `json:"policyId"` + NetworkLists []string `json:"networkLists"` + } + + // RemoveWAPBypassNetworkListsResponse is returned from a call to RemoveWAPBypassNetworkLists. + // Deprecated: this struct will be removed in a future release. + RemoveWAPBypassNetworkListsResponse struct { + NetworkLists []string `json:"networkLists"` + } +) + +// Validate validates a GetWAPBypassNetworkListsRequest. +func (v GetWAPBypassNetworkListsRequest) Validate() error { + return validation.Errors{ + "ConfigID": validation.Validate(v.ConfigID, validation.Required), + "Version": validation.Validate(v.Version, validation.Required), + "PolicyID": validation.Validate(v.PolicyID, validation.Required), + }.Filter() +} + +// Validate validates an UpdateWAPBypassNetworkListsRequest. +func (v UpdateWAPBypassNetworkListsRequest) Validate() error { + return validation.Errors{ + "ConfigID": validation.Validate(v.ConfigID, validation.Required), + "Version": validation.Validate(v.Version, validation.Required), + "PolicyID": validation.Validate(v.PolicyID, validation.Required), + }.Filter() +} + +// Validate validates a RemoveWAPBypassNetworkListsRequest. +// Deprecated: this method will be removed in a future release. +func (v RemoveWAPBypassNetworkListsRequest) Validate() error { + return validation.Errors{ + "ConfigID": validation.Validate(v.ConfigID, validation.Required), + "Version": validation.Validate(v.Version, validation.Required), + "PolicyID": validation.Validate(v.PolicyID, validation.Required), + }.Filter() +} + +func (p *appsec) GetWAPBypassNetworkLists(ctx context.Context, params GetWAPBypassNetworkListsRequest) (*GetWAPBypassNetworkListsResponse, error) { + logger := p.Log(ctx) + logger.Debugf("GetWAPBypassNetworkLists(%+v)", params) + + if err := params.Validate(); err != nil { + return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) + } + + var rval GetWAPBypassNetworkListsResponse + + uri := fmt.Sprintf( + "/appsec/v1/configs/%d/versions/%d/security-policies/%s/bypass-network-lists", + params.ConfigID, + params.Version, + params.PolicyID, + ) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, fmt.Errorf("failed to create GetWAPBypassNetworkLists request: %w", err) + } + + resp, err := p.Exec(req, &rval) + if err != nil { + return nil, fmt.Errorf("GetWAPBypassNetworkLists request failed: %w", err) + } + + if resp.StatusCode != http.StatusOK { + return nil, p.Error(resp) + } + + return &rval, nil + +} + +func (p *appsec) UpdateWAPBypassNetworkLists(ctx context.Context, params UpdateWAPBypassNetworkListsRequest) (*UpdateWAPBypassNetworkListsResponse, error) { + logger := p.Log(ctx) + logger.Debugf("UpdateWAPBypassNetworkLists(%+v)", params) + + if err := params.Validate(); err != nil { + return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) + } + + putURL := fmt.Sprintf( + "/appsec/v1/configs/%d/versions/%d/security-policies/%s/bypass-network-lists", + params.ConfigID, + params.Version, + params.PolicyID, + ) + + req, err := http.NewRequestWithContext(ctx, http.MethodPut, putURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create UpdateWAPBypassNetworkLists request: %w", err) + } + + var rval UpdateWAPBypassNetworkListsResponse + resp, err := p.Exec(req, &rval, params) + if err != nil { + return nil, fmt.Errorf("UpdateWAPBypassNetworkLists request failed: %w", err) + } + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return nil, p.Error(resp) + } + + return &rval, nil +} + +// Deprecated: this method will be removed in a future release. +func (p *appsec) RemoveWAPBypassNetworkLists(ctx context.Context, params RemoveWAPBypassNetworkListsRequest) (*RemoveWAPBypassNetworkListsResponse, error) { + logger := p.Log(ctx) + logger.Debugf("RemoveWAPBypassNetworkLists(%+v)", params) + + if err := params.Validate(); err != nil { + return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) + } + + putURL := fmt.Sprintf( + "/appsec/v1/configs/%d/versions/%d/security-policies/%s/bypass-network-lists", + params.ConfigID, + params.Version, + params.PolicyID, + ) + + req, err := http.NewRequestWithContext(ctx, http.MethodPut, putURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create RemoveWAPBypassNetworkLists request: %w", err) + } + + var rval RemoveWAPBypassNetworkListsResponse + resp, err := p.Exec(req, &rval, params) + if err != nil { + return nil, fmt.Errorf("RemoveWAPBypassNetworkLists request failed: %w", err) + } + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return nil, p.Error(resp) + } + + return &rval, nil +} diff --git a/pkg/appsec/wap_bypass_network_lists_test.go b/pkg/appsec/wap_bypass_network_lists_test.go new file mode 100644 index 00000000..afff10a0 --- /dev/null +++ b/pkg/appsec/wap_bypass_network_lists_test.go @@ -0,0 +1,278 @@ +package appsec + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAppSec_ListWAPBypassNetworkLists(t *testing.T) { + + result := GetWAPBypassNetworkListsResponse{} + + respData := compactJSON(loadFixtureBytes("testdata/TestBypassNetworkLists/BypassNetworkLists.json")) + json.Unmarshal([]byte(respData), &result) + + tests := map[string]struct { + params GetWAPBypassNetworkListsRequest + responseStatus int + responseBody string + expectedPath string + expectedResponse *GetWAPBypassNetworkListsResponse + withError error + headers http.Header + }{ + "200 OK": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + headers: http.Header{ + "Content-Type": []string{"application/json"}, + }, + responseStatus: http.StatusOK, + responseBody: string(respData), + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + expectedResponse: &result, + }, + "validation error - missing PolicyID": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + }, + withError: ErrStructValidation, + }, + "401 Not authorized - incorrect credentials": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + responseStatus: http.StatusUnauthorized, + responseBody: ` +{ + "type": "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", + "title": "Not authorized", + "status": 401, + "detail": "Inactive client token", + "instance": "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens" +}`, + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + withError: &Error{ + Type: "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", + Title: "Not authorized", + Detail: "Inactive client token", + Instance: "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens", + StatusCode: 401, + }, + }, + "500 internal server error": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + headers: http.Header{}, + responseStatus: http.StatusInternalServerError, + responseBody: ` +{ + "type": "internal_error", + "title": "Internal Server Error", + "detail": "Error fetching WAPBypassNetworkLists", + "status": 500 +}`, + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + withError: &Error{ + Type: "internal_error", + Title: "Internal Server Error", + Detail: "Error fetching WAPBypassNetworkLists", + StatusCode: http.StatusInternalServerError, + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, test.expectedPath, r.URL.String()) + assert.Equal(t, http.MethodGet, r.Method) + w.WriteHeader(test.responseStatus) + _, err := w.Write([]byte(test.responseBody)) + assert.NoError(t, err) + })) + client := mockAPIClient(t, mockServer) + result, err := client.GetWAPBypassNetworkLists( + session.ContextWithOptions( + context.Background(), + session.WithContextHeaders(test.headers), + ), + test.params) + if test.withError != nil { + assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) + return + } + require.NoError(t, err) + assert.Equal(t, test.expectedResponse, result) + }) + } +} + +func TestAppSec_GetWAPBypassNetworkLists(t *testing.T) { + + result := GetWAPBypassNetworkListsResponse{} + + respData := compactJSON(loadFixtureBytes("testdata/TestBypassNetworkLists/BypassNetworkLists.json")) + json.Unmarshal([]byte(respData), &result) + + tests := map[string]struct { + params GetWAPBypassNetworkListsRequest + responseStatus int + responseBody string + expectedPath string + expectedResponse *GetWAPBypassNetworkListsResponse + withError error + }{ + "200 OK": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + responseStatus: http.StatusOK, + responseBody: respData, + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + expectedResponse: &result, + }, + "500 internal server error": { + params: GetWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + responseStatus: http.StatusInternalServerError, + responseBody: (` +{ + "type": "internal_error", + "title": "Internal Server Error", + "detail": "Error fetching WAPBypassNetworkLists" +}`), + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + withError: &Error{ + Type: "internal_error", + Title: "Internal Server Error", + Detail: "Error fetching WAPBypassNetworkLists", + StatusCode: http.StatusInternalServerError, + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, test.expectedPath, r.URL.String()) + assert.Equal(t, http.MethodGet, r.Method) + w.WriteHeader(test.responseStatus) + _, err := w.Write([]byte(test.responseBody)) + assert.NoError(t, err) + })) + client := mockAPIClient(t, mockServer) + result, err := client.GetWAPBypassNetworkLists(context.Background(), test.params) + if test.withError != nil { + assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) + return + } + require.NoError(t, err) + assert.Equal(t, test.expectedResponse, result) + }) + } +} + +func TestAppSec_UpdateWAPBypassNetworkLists(t *testing.T) { + result := UpdateWAPBypassNetworkListsResponse{} + + respData := compactJSON(loadFixtureBytes("testdata/TestBypassNetworkLists/BypassNetworkLists.json")) + json.Unmarshal([]byte(respData), &result) + + req := UpdateWAPBypassNetworkListsRequest{} + + reqData := compactJSON(loadFixtureBytes("testdata/TestBypassNetworkLists/BypassNetworkLists.json")) + json.Unmarshal([]byte(reqData), &req) + + tests := map[string]struct { + params UpdateWAPBypassNetworkListsRequest + responseStatus int + responseBody string + expectedPath string + expectedResponse *UpdateWAPBypassNetworkListsResponse + withError error + headers http.Header + }{ + "200 Success": { + params: UpdateWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + headers: http.Header{ + "Content-Type": []string{"application/json;charset=UTF-8"}, + }, + responseStatus: http.StatusCreated, + responseBody: respData, + expectedResponse: &result, + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + }, + "500 internal server error": { + params: UpdateWAPBypassNetworkListsRequest{ + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + }, + responseStatus: http.StatusInternalServerError, + responseBody: (` +{ + "type": "internal_error", + "title": "Internal Server Error", + "detail": "Error creating WAPBypassNetworkLists" +}`), + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/bypass-network-lists", + withError: &Error{ + Type: "internal_error", + Title: "Internal Server Error", + Detail: "Error creating WAPBypassNetworkLists", + StatusCode: http.StatusInternalServerError, + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPut, r.Method) + w.WriteHeader(test.responseStatus) + if len(test.responseBody) > 0 { + _, err := w.Write([]byte(test.responseBody)) + assert.NoError(t, err) + } + })) + client := mockAPIClient(t, mockServer) + result, err := client.UpdateWAPBypassNetworkLists( + session.ContextWithOptions( + context.Background(), + session.WithContextHeaders(test.headers)), test.params) + if test.withError != nil { + assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) + return + } + require.NoError(t, err) + assert.Equal(t, test.expectedResponse, result) + }) + } +} From 3a7d675b73ea5b642debd6e750fc5355e60b885e Mon Sep 17 00:00:00 2001 From: aignachk Date: Tue, 5 Apr 2022 08:59:53 -0400 Subject: [PATCH 6/8] SECKSD-13717 added recommendations for eval rulesets and group section to ruleset upgrade info SECKSD-13227 added recommendations for eval rulesets and group section to ruleset upgrade info --- pkg/appsec/rule_upgrade.go | 79 +++++++++-------------- pkg/appsec/tuning_recommendations.go | 42 ++++++++---- pkg/appsec/tuning_recommendations_test.go | 40 ++++++------ 3 files changed, 84 insertions(+), 77 deletions(-) diff --git a/pkg/appsec/rule_upgrade.go b/pkg/appsec/rule_upgrade.go index ea78a160..3dcaa894 100644 --- a/pkg/appsec/rule_upgrade.go +++ b/pkg/appsec/rule_upgrade.go @@ -23,58 +23,41 @@ type ( // GetRuleUpgradeRequest is used to verify changes in the KRS rule sets. GetRuleUpgradeRequest struct { - ConfigID int `json:"-"` - Version int `json:"-"` - PolicyID string `json:"-"` + ConfigID int + Version int + PolicyID string } // GetRuleUpgradeResponse is returned from a call to GetRuleUpgrade. GetRuleUpgradeResponse struct { - Current string `json:"current,omitempty"` - Evaluating string `json:"evaluating,omitempty"` - Latest string `json:"latest,omitempty"` - KRSToEvalUpdates struct { - DeletedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"deletedRules,omitempty"` - UpdatedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"updatedRules,omitempty"` - NewRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"newRules,omitempty"` - } `json:"KRSToEvalUpdates,omitempty"` - EvalToEvalUpdates struct { - DeletedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"deletedRules,omitempty"` - UpdatedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"updatedRules,omitempty"` - NewRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"newRules,omitempty"` - } `json:"EvalToEvalUpdates,omitempty"` - KRSToLatestUpdates struct { - DeletedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"deletedRules,omitempty"` - NewRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"newRules,omitempty"` - UpdatedRules []struct { - ID int `json:"id,omitempty"` - Title string `json:"title,omitempty"` - } `json:"updatedRules,omitempty"` - } `json:"KRSToLatestUpdates,omitempty"` + Current string `json:"current,omitempty"` + Evaluating string `json:"evaluating,omitempty"` + Latest string `json:"latest,omitempty"` + KRSToEvalUpdates *RulesetUpdateData `json:"KRSToEvalUpdates,omitempty"` + EvalToEvalUpdates *RulesetUpdateData `json:"EvalToEvalUpdates,omitempty"` + KRSToLatestUpdates *RulesetUpdateData `json:"KRSToLatestUpdates,omitempty"` + } + + // RulesetUpdateData is used to report all updates to rules and attack groups in the ruleset. + RulesetUpdateData struct { + DeletedRules *RuleData `json:"deletedRules,omitempty"` + NewRules *RuleData `json:"newRules,omitempty"` + UpdatedRules *RuleData `json:"updatedRules,omitempty"` + DeletedAttackGroups *GroupData `json:"deletedAttackGroups,omitempty"` + UpdatedAttackGroups *GroupData `json:"updatedAttackGroups,omitempty"` + NewAttackGroups *GroupData `json:"newAttackGroups,omitempty"` + } + + // RuleData contains updates to rules + RuleData []struct { + ID int `json:"id,omitempty"` + Title string `json:"title,omitempty"` + } + + // GroupData contains updates to attack groups + GroupData []struct { + Group int `json:"group,omitempty"` + GroupName string `json:"groupName,omitempty"` } // UpdateRuleUpgradeRequest is used to upgrade to the most recent version of the KRS rule set. diff --git a/pkg/appsec/tuning_recommendations.go b/pkg/appsec/tuning_recommendations.go index a66ea0f0..7ed2960a 100644 --- a/pkg/appsec/tuning_recommendations.go +++ b/pkg/appsec/tuning_recommendations.go @@ -22,17 +22,19 @@ type ( // GetTuningRecommendationsRequest is used to retrieve tuning recommendations for a security policy. GetTuningRecommendationsRequest struct { - ConfigID int `json:"-"` - Version int `json:"-"` - PolicyID string `json:"-"` + ConfigID int + Version int + PolicyID string + RulesetType RulesetType } // GetAttackGroupRecommendationsRequest is used to retrieve tuning recommendations for a specific attack group. GetAttackGroupRecommendationsRequest struct { - ConfigID int `json:"-"` - Version int `json:"-"` - PolicyID string `json:"-"` - Group string `json:"group"` + ConfigID int + Version int + PolicyID string + Group string + RulesetType RulesetType } // GetTuningRecommendationsResponse is returned from a call to GetTuningRecommendations. @@ -59,6 +61,17 @@ type ( PathEvidences []string `json:"pathEvidences,omitempty"` UserDataEvidences []string `json:"userDataEvidences,omitempty"` } + + // RulesetType is a ruleset type value + RulesetType string +) + +const ( + // RulesetTypeActive for active rulesets + RulesetTypeActive RulesetType = "active" + + // RulesetTypeEvaluation for evaluation rulesets + RulesetTypeEvaluation RulesetType = "evaluation" ) // Validate validates a GetTuningRecommendationsRequest. @@ -67,6 +80,8 @@ func (v GetTuningRecommendationsRequest) Validate() error { "ConfigID": validation.Validate(v.ConfigID, validation.Required), "Version": validation.Validate(v.Version, validation.Required), "PolicyID": validation.Validate(v.PolicyID, validation.Required), + "RulesetType": validation.Validate(v.RulesetType, validation.In(RulesetTypeActive, RulesetTypeEvaluation).Error( + fmt.Sprintf("value '%s' is invalid. Must be one of: 'active', 'evaluation' or '' (empty)", v.RulesetType))), }.Filter() } @@ -77,6 +92,8 @@ func (v GetAttackGroupRecommendationsRequest) Validate() error { "Version": validation.Validate(v.Version, validation.Required), "PolicyID": validation.Validate(v.PolicyID, validation.Required), "Group": validation.Validate(v.Group, validation.Required), + "RulesetType": validation.Validate(v.RulesetType, validation.In(RulesetTypeActive, RulesetTypeEvaluation).Error( + fmt.Sprintf("value '%s' is invalid. Must be one of: 'active', 'evaluation' or '' (empty)", v.RulesetType))), }.Filter() } @@ -91,10 +108,11 @@ func (p *appsec) GetTuningRecommendations(ctx context.Context, params GetTuningR var rval GetTuningRecommendationsResponse uri := fmt.Sprintf( - "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations?standardException=true", + "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations?standardException=true&type=%s", params.ConfigID, params.Version, - params.PolicyID) + params.PolicyID, + params.RulesetType) req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) if err != nil { @@ -127,11 +145,13 @@ func (p *appsec) GetAttackGroupRecommendations(ctx context.Context, params GetAt var rval GetAttackGroupRecommendationsResponse uri := fmt.Sprintf( - "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations/attack-groups/%s?standardException=true", + "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations/attack-groups/%s?standardException=true&type=%s", params.ConfigID, params.Version, params.PolicyID, - params.Group) + params.Group, + params.RulesetType, + ) req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) if err != nil { diff --git a/pkg/appsec/tuning_recommendations_test.go b/pkg/appsec/tuning_recommendations_test.go index 3e698788..183edbe1 100644 --- a/pkg/appsec/tuning_recommendations_test.go +++ b/pkg/appsec/tuning_recommendations_test.go @@ -31,23 +31,25 @@ func TestAppSec_GetTuningRecommendations(t *testing.T) { }{ "200 OK": { params: GetTuningRecommendationsRequest{ - ConfigID: 43253, - Version: 15, - PolicyID: "AAAA_81230", + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + RulesetType: RulesetTypeActive, }, headers: http.Header{ "Content-Type": []string{"application/json"}, }, responseStatus: http.StatusOK, responseBody: string(respData), - expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations?standardException=true", + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations?standardException=true&type=active", expectedResponse: &result, }, "500 internal server error": { params: GetTuningRecommendationsRequest{ - ConfigID: 43253, - Version: 15, - PolicyID: "AAAA_81230", + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + RulesetType: RulesetTypeEvaluation, }, headers: http.Header{}, responseStatus: http.StatusInternalServerError, @@ -58,7 +60,7 @@ func TestAppSec_GetTuningRecommendations(t *testing.T) { "detail": "Error fetching propertys", "status": 500 }`, - expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations?standardException=true", + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations?standardException=true&type=evaluation", withError: &Error{ Type: "internal_error", Title: "Internal Server Error", @@ -112,25 +114,27 @@ func TestAppSec_GetAttackGroupRecommendations(t *testing.T) { }{ "200 OK": { params: GetAttackGroupRecommendationsRequest{ - ConfigID: 43253, - Version: 15, - PolicyID: "AAAA_81230", - Group: "XSS", + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + Group: "XSS", + RulesetType: RulesetTypeEvaluation, }, headers: http.Header{ "Content-Type": []string{"application/json"}, }, responseStatus: http.StatusOK, responseBody: string(respData), - expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations/attack-groups/XSS?standardException=true", + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations/attack-groups/XSS?standardException=true&type=evaluation", expectedResponse: &result, }, "500 internal server error": { params: GetAttackGroupRecommendationsRequest{ - ConfigID: 43253, - Version: 15, - PolicyID: "AAAA_81230", - Group: "XSS", + ConfigID: 43253, + Version: 15, + PolicyID: "AAAA_81230", + Group: "XSS", + RulesetType: RulesetTypeActive, }, headers: http.Header{}, responseStatus: http.StatusInternalServerError, @@ -141,7 +145,7 @@ func TestAppSec_GetAttackGroupRecommendations(t *testing.T) { "detail": "Error fetching propertys", "status": 500 }`, - expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations/attack-groups/XSS?standardException=true", + expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/recommendations/attack-groups/XSS?standardException=true&type=active", withError: &Error{ Type: "internal_error", Title: "Internal Server Error", From ebf63fb56b6d0676aeae5182aa15a4256b486830 Mon Sep 17 00:00:00 2001 From: aignachk Date: Tue, 19 Apr 2022 23:51:12 -0400 Subject: [PATCH 7/8] SECKSD-14400 export eval attack groups SECKSD-14400 export eval attack groups --- pkg/appsec/export_configuration.go | 6 +- .../ExportConfiguration.json | 136 ++++++++++++++++++ 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/pkg/appsec/export_configuration.go b/pkg/appsec/export_configuration.go index 1fb529e7..39dbdc5d 100644 --- a/pkg/appsec/export_configuration.go +++ b/pkg/appsec/export_configuration.go @@ -651,8 +651,10 @@ type ( // WebApplicationFirewallEvaluation is returned as part of GetExportConfigurationResponse. WebApplicationFirewallEvaluation struct { AttackGroupActions []struct { - Action string `json:"action"` - Group string `json:"group"` + Action string `json:"action"` + Group string `json:"group"` + Exception *RuleException `json:"exception,omitempty"` + AdvancedExceptionsList *AdvancedExceptions `json:"advancedExceptions,omitempty"` } `json:"attackGroupActions,omitempty"` EvaluationID int `json:"evaluationId"` EvaluationVersion int `json:"evaluationVersion"` diff --git a/pkg/appsec/testdata/TestExportConfiguration/ExportConfiguration.json b/pkg/appsec/testdata/TestExportConfiguration/ExportConfiguration.json index 363e0e53..f346bae3 100644 --- a/pkg/appsec/testdata/TestExportConfiguration/ExportConfiguration.json +++ b/pkg/appsec/testdata/TestExportConfiguration/ExportConfiguration.json @@ -4723,6 +4723,142 @@ "applyReputationControls": true, "applySlowPostControls": true }, + "webApplicationFirewall": { + "ruleActions": [ + { + "action": "alert", + "id": 950002, + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "id": 950006, + "rulesetVersionId": 7392 + } + ], + "attackGroupActions": [ + { + "action": "alert", + "group": "POLICY", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "WAT", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "PROTOCOL", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "SQL", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "XSS", + "rulesetVersionId": 7392, + "exception": { + "specificHeaderCookieParamXmlOrJsonNames": [ + { + "names": [ + "ASE-Manual-EVAL-HEADER" + ], + "selector": "REQUEST_HEADERS" + } + ] + } + }, + { + "action": "alert", + "group": "CMD", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "LFI", + "rulesetVersionId": 7392, + "exception": { + "specificHeaderCookieParamXmlOrJsonNames": [ + { + "names": [ + "ASE-Manual-Active-COOKIES" + ], + "selector": "REQUEST_COOKIES", + "wildcard": true + } + ] + } + }, + { + "action": "alert", + "group": "RFI", + "rulesetVersionId": 7392 + }, + { + "action": "alert", + "group": "PLATFORM", + "rulesetVersionId": 7392 + } + ], + "evaluation": { + "attackGroupActions": [ + { + "action": "alert", + "group": "POLICY" + }, + { + "action": "alert", + "group": "WAT" + }, + { + "action": "alert", + "group": "PROTOCOL" + }, + { + "action": "alert", + "group": "SQL" + }, + { + "action": "alert", + "group": "XSS" + }, + { + "action": "deny", + "group": "CMD" + }, + { + "action": "alert", + "group": "LFI" + }, + { + "action": "alert", + "group": "RFI" + }, + { + "action": "alert", + "group": "PLATFORM" + } + ], + "evaluationId": 13904, + "evaluationVersion": 1, + "ruleActions": [ + { + "action": "alert", + "id": 950002 + }, + { + "action": "alert", + "id": 950006 + } + ], + "rulesetVersionId": 7592 + }, + "threatIntel": "on" + }, "apiRequestConstraints": { "apiEndpoints": [] }, From 68bbd197897289237c74bde0a9bf6fb8d6141e02 Mon Sep 17 00:00:00 2001 From: Roberto Lopez Lopez Date: Wed, 20 Apr 2022 10:16:05 +0000 Subject: [PATCH 8/8] DXE-944 release 2.12.0 --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 489ea033..b73c6fd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # EDGEGRID GOLANG RELEASE NOTES -## 2.xx.x (Apr. xx, 2022) +## 2.12.0 (Apr. 25, 2022) #### FEATURES/ENHANCEMENTS: * APPSEC * Add WAPBypassNetworkLists interface, to be used in preference to deprecated BypassNetworkLists interface. +* Support for account switch keys from environment ([#149](https://github.com/akamai/AkamaiOPEN-edgegrid-golang/pull/149)) + ## 2.11.0 (March 24, 2022) #### FEATURES/ENHANCEMENTS: