diff --git a/internal/api/policy/2024-10-15/policy.go b/internal/api/policy/2024-10-15/policy.go index 04de3fcf3..9b3425650 100644 --- a/internal/api/policy/2024-10-15/policy.go +++ b/internal/api/policy/2024-10-15/policy.go @@ -35,6 +35,15 @@ const ( PolicyAttributesActionTypeIgnore PolicyAttributesActionType = "ignore" ) +// Defines values for PolicyAttributesSource. +const ( + Api PolicyAttributesSource = "api" + Cli PolicyAttributesSource = "cli" + Ide PolicyAttributesSource = "ide" + Unknown PolicyAttributesSource = "unknown" + Web PolicyAttributesSource = "web" +) + // Defines values for PolicyConditionField. const ( Snykassetfindingv1 PolicyConditionField = "snyk/asset/finding/v1" @@ -78,7 +87,6 @@ const ( // Defines values for PolicyReview. const ( PolicyReviewApproved PolicyReview = "approved" - PolicyReviewCancelled PolicyReview = "cancelled" PolicyReviewNotRequired PolicyReview = "not-required" PolicyReviewPending PolicyReview = "pending" PolicyReviewRejected PolicyReview = "rejected" @@ -96,6 +104,34 @@ const ( UpdatePolicyReviewRejected UpdatePolicyReview = "rejected" ) +// Defines values for OrderBy. +const ( + OrderByCreated OrderBy = "created" + OrderByExpires OrderBy = "expires" + OrderByIgnoreType OrderBy = "ignore-type" + OrderByRequestedBy OrderBy = "requested-by" +) + +// Defines values for OrderDirection. +const ( + OrderDirectionAsc OrderDirection = "asc" + OrderDirectionDesc OrderDirection = "desc" +) + +// Defines values for GetOrgPoliciesParamsOrderBy. +const ( + GetOrgPoliciesParamsOrderByCreated GetOrgPoliciesParamsOrderBy = "created" + GetOrgPoliciesParamsOrderByExpires GetOrgPoliciesParamsOrderBy = "expires" + GetOrgPoliciesParamsOrderByIgnoreType GetOrgPoliciesParamsOrderBy = "ignore-type" + GetOrgPoliciesParamsOrderByRequestedBy GetOrgPoliciesParamsOrderBy = "requested-by" +) + +// Defines values for GetOrgPoliciesParamsOrderDirection. +const ( + GetOrgPoliciesParamsOrderDirectionAsc GetOrgPoliciesParamsOrderDirection = "asc" + GetOrgPoliciesParamsOrderDirectionDesc GetOrgPoliciesParamsOrderDirection = "desc" +) + // ActualVersion Resolved API version type ActualVersion = string @@ -219,16 +255,23 @@ type PolicyAttributes struct { ActionType PolicyAttributesActionType `json:"action_type"` ConditionsGroup PolicyConditionsGroup `json:"conditions_group"` Name string `json:"name"` + + // Source The source of the policy creation. Defaults to 'api' if not provided. + Source *PolicyAttributesSource `json:"source,omitempty"` } // PolicyAttributesActionType defines model for PolicyAttributes.ActionType. type PolicyAttributesActionType string +// PolicyAttributesSource The source of the policy creation. Defaults to 'api' if not provided. +type PolicyAttributesSource string + // PolicyCondition defines model for PolicyCondition. type PolicyCondition struct { // Field field refers to the type of identifier used in the condition of the policy. The available value is versioned and hierarchical: // - `snyk/asset/finding/v1` : identity of the finding scoped to a Snyk assets (e.g. a repository). - // The identities can be extracted from the fingerprints section of the SARIF, which is accessible via the Snyk CLI. More details can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results). + // For a given issue, `snyk/asset/finding/v1` can be extracted from the `key_asset` field in the [issues API](https://apidocs.snyk.io/?version=2024-10-15#get-/orgs/-org_id-/issues). + // In addition, finding identities can be extracted from the fingerprints section of the SARIF, which is accessible via the Snyk CLI. More details can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results). Field PolicyConditionField `json:"field"` // Operator Operator for the field to value matching. Currently @@ -242,7 +285,8 @@ type PolicyCondition struct { // PolicyConditionField field refers to the type of identifier used in the condition of the policy. The available value is versioned and hierarchical: // - `snyk/asset/finding/v1` : identity of the finding scoped to a Snyk assets (e.g. a repository). -// The identities can be extracted from the fingerprints section of the SARIF, which is accessible via the Snyk CLI. More details can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results). +// For a given issue, `snyk/asset/finding/v1` can be extracted from the `key_asset` field in the [issues API](https://apidocs.snyk.io/?version=2024-10-15#get-/orgs/-org_id-/issues). +// In addition, finding identities can be extracted from the fingerprints section of the SARIF, which is accessible via the Snyk CLI. More details can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results). type PolicyConditionField string // PolicyConditionOperator Operator for the field to value matching. Currently @@ -401,6 +445,12 @@ type EndingBefore = string // Limit defines model for Limit. type Limit = int32 +// OrderBy defines model for OrderBy. +type OrderBy string + +// OrderDirection defines model for OrderDirection. +type OrderDirection string + // OrgId defines model for OrgId. type OrgId = openapi_types.UUID @@ -410,6 +460,9 @@ type PolicyId = openapi_types.UUID // Review defines model for Review. type Review = []PolicyReview +// Search defines model for Search. +type Search = string + // StartingAfter defines model for StartingAfter. type StartingAfter = string @@ -448,6 +501,15 @@ type GetOrgPoliciesParams struct { // Limit Number of results to return per page Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + // Search Search keyword for searching fields ignored_by.name, ignored_by.email, ignore_type in policy_rules + Search *Search `form:"search,omitempty" json:"search,omitempty"` + + // OrderBy The column name to sort on + OrderBy *GetOrgPoliciesParamsOrderBy `form:"order_by,omitempty" json:"order_by,omitempty"` + + // OrderDirection Sorting direction ASC/DESC + OrderDirection *GetOrgPoliciesParamsOrderDirection `form:"order_direction,omitempty" json:"order_direction,omitempty"` + // Review Policy rule review state e.g. approved Review *Review `form:"review,omitempty" json:"review,omitempty"` @@ -461,6 +523,12 @@ type GetOrgPoliciesParams struct { ExpiresNever *bool `form:"expires_never,omitempty" json:"expires_never,omitempty"` } +// GetOrgPoliciesParamsOrderBy defines parameters for GetOrgPolicies. +type GetOrgPoliciesParamsOrderBy string + +// GetOrgPoliciesParamsOrderDirection defines parameters for GetOrgPolicies. +type GetOrgPoliciesParamsOrderDirection string + // CreateOrgPolicyParams defines parameters for CreateOrgPolicy. type CreateOrgPolicyParams struct { // Version The requested version of the endpoint to process the request @@ -940,6 +1008,54 @@ func NewGetOrgPoliciesRequest(server string, orgId OrgId, params *GetOrgPolicies } + if params.Search != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "search", runtime.ParamLocationQuery, *params.Search); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.OrderBy != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "order_by", runtime.ParamLocationQuery, *params.OrderBy); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.OrderDirection != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "order_direction", runtime.ParamLocationQuery, *params.OrderDirection); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + if params.Review != nil { if queryFrag, err := runtime.StyleParamWithLocation("form", false, "review", runtime.ParamLocationQuery, *params.Review); err != nil { diff --git a/internal/api/policy/2024-10-15/spec.yaml b/internal/api/policy/2024-10-15/spec.yaml index 486485a98..fe0cccce8 100644 --- a/internal/api/policy/2024-10-15/spec.yaml +++ b/internal/api/policy/2024-10-15/spec.yaml @@ -54,12 +54,12 @@ components: A header containing the version stage of the endpoint. This stage describes the guarantees snyk provides surrounding stability of the endpoint. schema: enum: - - wip - - experimental - - beta - - ga - - deprecated - - sunset + - wip + - experimental + - beta + - ga + - deprecated + - sunset example: ga type: string parameters: @@ -82,6 +82,26 @@ components: minimum: 10 multipleOf: 10 type: integer + OrderBy: + description: The column name to sort on + in: query + name: order_by + schema: + enum: + - created + - expires + - ignore-type + - requested-by + type: string + OrderDirection: + description: Sorting direction ASC/DESC + in: query + name: order_direction + schema: + enum: + - asc + - desc + type: string OrgId: description: Org ID in: path @@ -108,6 +128,13 @@ components: $ref: '#/components/schemas/PolicyReview' type: array style: form + Search: + description: Search keyword for searching fields ignored_by.name, ignored_by.email, + ignore_type in policy_rules + in: query + name: search + schema: + type: string StartingAfter: description: Return the page of results immediately after this cursor example: v1.eyJpZCI6IjEwMDAifQo= @@ -273,14 +300,14 @@ components: $ref: '#/components/schemas/Meta' type: enum: - - policy + - policy type: string required: - - type - - attributes + - type + - attributes type: object required: - - data + - data type: object Error: additionalProperties: false @@ -338,22 +365,22 @@ components: example: Bad request type: string required: - - status - - detail + - status + - detail type: object ErrorDocument: additionalProperties: false example: errors: - - detail: Permission denied for this resource - status: "403" + - detail: Permission denied for this resource + status: "403" jsonapi: version: "1.0" properties: errors: example: - - detail: Permission denied for this resource - status: "403" + - detail: Permission denied for this resource + status: "403" items: $ref: '#/components/schemas/Error' minItems: 1 @@ -361,8 +388,8 @@ components: jsonapi: $ref: '#/components/schemas/JsonApi' required: - - jsonapi - - errors + - jsonapi + - errors type: object ErrorLink: additionalProperties: false @@ -385,27 +412,27 @@ components: pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)$ type: string required: - - version + - version type: object LinkProperty: example: https://example.com/api/resource oneOf: - - description: A string containing the link’s URL. - example: https://example.com/api/resource - type: string - - additionalProperties: false - example: - href: https://example.com/api/resource - properties: - href: - description: A string containing the link’s URL. - example: https://example.com/api/resource - type: string - meta: - $ref: '#/components/schemas/Meta' - required: - - href - type: object + - description: A string containing the link’s URL. + example: https://example.com/api/resource + type: string + - additionalProperties: false + example: + href: https://example.com/api/resource + properties: + href: + description: A string containing the link’s URL. + example: https://example.com/api/resource + type: string + meta: + $ref: '#/components/schemas/Meta' + required: + - href + type: object Links: additionalProperties: false properties: @@ -430,8 +457,8 @@ components: key2: sub_key: sub_value key3: - - array_value1 - - array_value2 + - array_value1 + - array_value2 type: object PaginatedLinks: additionalProperties: false @@ -457,7 +484,7 @@ components: data: $ref: '#/components/schemas/PolicyActionIgnoreData' required: - - data + - data type: object PolicyActionIgnoreData: additionalProperties: false @@ -468,14 +495,15 @@ components: type: string ignore_type: enum: - - wont-fix - - not-vulnerable - - temporary-ignore + - wont-fix + - not-vulnerable + - temporary-ignore type: string reason: + maxLength: 10000 type: string required: - - ignore_type + - ignore_type type: object PolicyAttributes: additionalProperties: false @@ -484,28 +512,43 @@ components: $ref: '#/components/schemas/PolicyActionIgnore' action_type: enum: - - ignore + - ignore type: string conditions_group: $ref: '#/components/schemas/PolicyConditionsGroup' name: + maxLength: 255 + type: string + source: + description: The source of the policy creation. Defaults to 'api' if not + provided. + enum: + - api + - cli + - ide + - web + - unknown type: string required: - - name - - conditions_group - - action - - action_type + - name + - conditions_group + - action + - action_type type: object PolicyCondition: additionalProperties: false properties: field: - description: | - field refers to the type of identifier used in the condition of the policy. The available value is versioned and hierarchical: - - `snyk/asset/finding/v1` : identity of the finding scoped to a Snyk assets (e.g. a repository). - The identities can be extracted from the fingerprints section of the SARIF, which is accessible via the Snyk CLI. More details can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results). + description: "field refers to the type of identifier used in the condition + of the policy. The available value is versioned and hierarchical:\n- + `snyk/asset/finding/v1` : identity of the finding scoped to a Snyk assets + (e.g. a repository).\nFor a given issue, `snyk/asset/finding/v1` can be + extracted from the `key_asset` field in the [issues API](https://apidocs.snyk.io/?version=2024-10-15#get-/orgs/-org_id-/issues). + \nIn addition, finding identities can be extracted from the fingerprints + section of the SARIF, which is accessible via the Snyk CLI. More details + can be found in the [CLI documentation](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/snyk-cli-for-snyk-code/view-snyk-code-cli-results#export-test-results).\n" enum: - - snyk/asset/finding/v1 + - snyk/asset/finding/v1 type: string operator: description: | @@ -513,16 +556,16 @@ components: only 'includes' is supported, which does an exact string match on the value. enum: - - includes + - includes type: string value: description: | The value of the field to match on. type: string required: - - field - - operator - - value + - field + - operator + - value type: object PolicyConditionsGroup: properties: @@ -536,11 +579,11 @@ components: description: The logical operator for the policy condition. Currently only 'and' is supported. enum: - - and + - and type: string required: - - logical_operator - - conditions + - logical_operator + - conditions type: object PolicyEventAttributes: additionalProperties: false @@ -558,10 +601,10 @@ components: type: $ref: '#/components/schemas/PolicyEventType' required: - - created_at - - type - - created_by - - changes + - created_at + - type + - created_by + - changes type: object PolicyEventChanges: additionalProperties: false @@ -595,21 +638,21 @@ components: type: string type: enum: - - policy_event + - policy_event type: string required: - - id - - type - - attributes + - id + - type + - attributes type: object PolicyEventType: enum: - - approve - - reject - - cancel - - reopen - - edit - - create + - approve + - reject + - cancel + - reopen + - edit + - create type: string PolicyResponse: additionalProperties: false @@ -623,12 +666,12 @@ components: type: string type: enum: - - policy + - policy type: string required: - - id - - type - - attributes + - id + - type + - attributes type: object PolicyResponseAttributes: additionalProperties: false @@ -637,7 +680,7 @@ components: $ref: '#/components/schemas/PolicyActionIgnore' action_type: enum: - - ignore + - ignore type: string conditions_group: $ref: '#/components/schemas/PolicyConditionsGroup' @@ -656,22 +699,21 @@ components: format: date-time type: string required: - - name - - conditions_group - - action - - action_type - - review - - created_at - - updated_at + - name + - conditions_group + - action + - action_type + - review + - created_at + - updated_at type: object PolicyReview: description: Review status. enum: - - pending - - approved - - rejected - - cancelled - - not-required + - pending + - approved + - rejected + - not-required type: string Principal: properties: @@ -686,8 +728,8 @@ components: description: Name of the user or service account that created the policy type: string required: - - name - - id + - name + - id type: object QueryVersion: description: Requested API version @@ -715,6 +757,7 @@ components: conditions_group: $ref: '#/components/schemas/PolicyConditionsGroup' name: + maxLength: 255 type: string review: $ref: '#/components/schemas/UpdatePolicyReview' @@ -736,14 +779,14 @@ components: $ref: '#/components/schemas/Meta' type: enum: - - policy + - policy type: string required: - - type - - attributes + - type + - attributes type: object required: - - data + - data type: object UpdatePolicyReview: description: | @@ -751,9 +794,9 @@ components: To provide an optional message relating to the review state change, add a string 'message' property to the 'meta' object. enum: - - pending - - approved - - rejected + - pending + - approved + - rejected type: string info: title: policy-service @@ -785,18 +828,18 @@ paths: "500": $ref: '#/components/responses/500' tags: - - OpenAPI + - OpenAPI /openapi/{version}: get: description: Get OpenAPI specification effective at version. operationId: getAPIVersion parameters: - - description: The requested version of the API - in: path - name: version - required: true - schema: - type: string + - description: The requested version of the API + in: path + name: version + required: true + schema: + type: string responses: "200": content: @@ -820,45 +863,46 @@ paths: "500": $ref: '#/components/responses/500' tags: - - OpenAPI + - OpenAPI /orgs/{org_id}/policies: get: - description: | - Get all policies for the requested organisation. - - *Org level Policy APIs Access Notice:* Access to our Org level Policy APIs is currently - restricted via "snykCodeConsistentIgnores" feature flag and will result in a 403 Forbidden error - without the flag enabled. Please contact your account representative for - eligibility requirements. + description: "Get all policies for the requested organisation.\n\n*Org level + Policy APIs Access Notice:* Org level Policy APIs are only available \nfor + use with Code Consistent Ignores. For information about how to enable Code + Consistent Ignores \nsee [this](https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code#enable-snyk-code-consistent-ignores) + \ndocumentation.\n" operationId: getOrgPolicies parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/StartingAfter' - - $ref: '#/components/parameters/EndingBefore' - - $ref: '#/components/parameters/Limit' - - $ref: '#/components/parameters/OrgId' - - $ref: '#/components/parameters/Review' - - description: Select only policies with an expiry strictly before the given - time. - in: query - name: expires_before - schema: - example: "2024-03-16T00:00:00Z" - format: date-time - type: string - - description: Select only policies with an expiry strictly past the given time. - in: query - name: expires_after - schema: - example: "2024-03-16T00:00:00Z" - format: date-time - type: string - - description: Select only policies that never expire. - in: query - name: expires_never - schema: - example: true - type: boolean + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/StartingAfter' + - $ref: '#/components/parameters/EndingBefore' + - $ref: '#/components/parameters/Limit' + - $ref: '#/components/parameters/Search' + - $ref: '#/components/parameters/OrderBy' + - $ref: '#/components/parameters/OrderDirection' + - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/Review' + - description: Select only policies with an expiry strictly before the given + time. + in: query + name: expires_before + schema: + example: "2024-03-16T00:00:00Z" + format: date-time + type: string + - description: Select only policies with an expiry strictly past the given time. + in: query + name: expires_after + schema: + example: "2024-03-16T00:00:00Z" + format: date-time + type: string + - description: Select only policies that never expire. + in: query + name: expires_never + schema: + example: true + type: boolean responses: "200": content: @@ -875,8 +919,8 @@ paths: links: $ref: '#/components/schemas/PaginatedLinks' required: - - jsonapi - - data + - jsonapi + - data type: object description: The policies for the requested organisation. headers: @@ -906,43 +950,37 @@ paths: $ref: '#/components/responses/404' summary: Get org-level policies tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.read + - project.ignore.read type: org enableAccessAudit: true x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - "2024-10-15" + - "2024-10-15" x-snyk-api-resource: policies x-snyk-api-stability: ga x-snyk-api-version: "2024-10-15" x-stability-level: stable post: - description: | - Create a new org-level policy. - - *Org level Policy APIs Access Notice:* Access to our Org level Policy APIs is currently - restricted via "snykCodeConsistentIgnores" feature flag and will result in a 403 Forbidden error - without the flag enabled. Please contact your account representative for - eligibility requirements. + description: "Create a new org-level policy.\n\n*Org level Policy APIs Access + Notice:* Org level Policy APIs are only available \nfor use with Code Consistent + Ignores. For information about how to enable Code Consistent Ignores \nsee + [this](https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code#enable-snyk-code-consistent-ignores) + \ndocumentation.\n" operationId: createOrgPolicy parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/OrgId' requestBody: content: application/vnd.api+json: @@ -962,8 +1000,8 @@ paths: links: $ref: '#/components/schemas/SelfLink' required: - - jsonapi - - data + - jsonapi + - data type: object description: A single policy is returned if it is successfully created. headers: @@ -998,45 +1036,39 @@ paths: $ref: '#/components/responses/500' summary: Create a new org-level policy tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.create + - project.ignore.create type: org enableAccessAudit: true x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - "2024-10-15" + - "2024-10-15" x-snyk-api-resource: policies x-snyk-api-stability: ga x-snyk-api-version: "2024-10-15" x-stability-level: stable /orgs/{org_id}/policies/{policy_id}: delete: - description: | - Delete an existing org-level policy. - - *Org level Policy APIs Access Notice:* Access to our Org level Policy APIs is currently - restricted via "snykCodeConsistentIgnores" feature flag and will result in a 403 Forbidden error - without the flag enabled. Please contact your account representative for - eligibility requirements. + description: "Delete an existing org-level policy.\n\n*Org level Policy APIs + Access Notice:* Org level Policy APIs are only available \nfor use with Code + Consistent Ignores. For information about how to enable Code Consistent Ignores + \nsee [this](https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code#enable-snyk-code-consistent-ignores) + \ndocumentation.\n" operationId: deleteOrgPolicy parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/OrgId' - - $ref: '#/components/parameters/PolicyId' + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/PolicyId' responses: "204": $ref: '#/components/responses/204' @@ -1052,44 +1084,38 @@ paths: $ref: '#/components/responses/500' summary: Delete an org-level policy tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.delete + - project.ignore.delete type: org enableAccessAudit: true x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - "2024-10-15" + - "2024-10-15" x-snyk-api-resource: policies x-snyk-api-stability: ga x-snyk-api-version: "2024-10-15" x-stability-level: stable get: - description: | - Get a specific org-level policy based on its ID. - - *Org level Policy APIs Access Notice:* Access to our Org level Policy APIs is currently - restricted via "snykCodeConsistentIgnores" feature flag and will result in a 403 Forbidden error - without the flag enabled. Please contact your account representative for - eligibility requirements. + description: "Get a specific org-level policy based on its ID.\n\n*Org level + Policy APIs Access Notice:* Org level Policy APIs are only available \nfor + use with Code Consistent Ignores. For information about how to enable Code + Consistent Ignores \nsee [this](https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code#enable-snyk-code-consistent-ignores) + \ndocumentation.\n" operationId: getOrgPolicy parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/OrgId' - - $ref: '#/components/parameters/PolicyId' + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/PolicyId' responses: "200": content: @@ -1104,8 +1130,8 @@ paths: links: $ref: '#/components/schemas/Links' required: - - jsonapi - - data + - jsonapi + - data type: object description: The requested policy. headers: @@ -1135,42 +1161,38 @@ paths: $ref: '#/components/responses/404' summary: Get an org-level policy tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.read + - project.ignore.read type: org enableAccessAudit: true x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - "2024-10-15" + - "2024-10-15" x-snyk-api-resource: policies x-snyk-api-stability: ga x-snyk-api-version: "2024-10-15" x-stability-level: stable patch: description: "Update the org-level policy. \n\n*Org level Policy APIs Access - Notice:* Access to our Org level Policy APIs is currently\nrestricted via - \"snykCodeConsistentIgnores\" feature flag and will result in a 403 Forbidden - error\nwithout the flag enabled. Please contact your account representative - for\neligibility requirements.\n" + Notice:* Org level Policy APIs are only available \nfor use with Code Consistent + Ignores. For information about how to enable Code Consistent Ignores \nsee + [this](https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code#enable-snyk-code-consistent-ignores) + \ndocumentation.\n" operationId: updateOrgPolicy parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/OrgId' - - $ref: '#/components/parameters/PolicyId' + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/PolicyId' requestBody: content: application/vnd.api+json: @@ -1190,8 +1212,8 @@ paths: links: $ref: '#/components/schemas/SelfLink' required: - - jsonapi - - data + - jsonapi + - data type: object description: A single policy is returned if it is successfully updated. headers: @@ -1226,27 +1248,23 @@ paths: $ref: '#/components/responses/409' summary: Update an org-level policy tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.edit + - project.ignore.edit type: org enableAccessAudit: true x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - "2024-10-15" + - "2024-10-15" x-snyk-api-resource: policies x-snyk-api-stability: ga x-snyk-api-version: "2024-10-15" @@ -1262,12 +1280,12 @@ paths: account representative for eligibility requirements. operationId: getOrgPolicyEvents parameters: - - $ref: '#/components/parameters/Version' - - $ref: '#/components/parameters/StartingAfter' - - $ref: '#/components/parameters/EndingBefore' - - $ref: '#/components/parameters/Limit' - - $ref: '#/components/parameters/OrgId' - - $ref: '#/components/parameters/PolicyId' + - $ref: '#/components/parameters/Version' + - $ref: '#/components/parameters/StartingAfter' + - $ref: '#/components/parameters/EndingBefore' + - $ref: '#/components/parameters/Limit' + - $ref: '#/components/parameters/OrgId' + - $ref: '#/components/parameters/PolicyId' responses: "200": content: @@ -1284,8 +1302,8 @@ paths: links: $ref: '#/components/schemas/PaginatedLinks' required: - - jsonapi - - data + - jsonapi + - data type: object description: The requested policy. headers: @@ -1315,40 +1333,41 @@ paths: $ref: '#/components/responses/404' summary: List org policy events tags: - - Policies + - Policies x-cerberus: authorization: - featureFlag: - tenant: - pathId: org_id - values: - - snykCodeConsistentIgnores - - ignoreApprovalWorkflow resource: entitlements: - - api + - api pathId: org_id permissions: - - project.ignore.read + - project.ignore.read type: org enableAccessAudit: true + featureFlag: + tenant: + pathId: org_id + values: + - snykCodeConsistentIgnores + - ignoreApprovalWorkflow x-snyk-api-lifecycle: released x-snyk-api-owners: - - '@snyk/ignores' + - '@snyk/ignores' + - '@snyk/appsec_ignores' x-snyk-api-releases: - - 2024-10-13~beta + - 2024-10-13~beta x-snyk-api-resource: policyevents x-snyk-api-stability: beta x-snyk-api-version: 2024-10-13~beta x-stability-level: beta servers: - - description: policy-service - url: /rest +- description: policy-service + url: /rest tags: - - description: The OpenAPI specification for policy-service. - name: OpenAPI +- description: The OpenAPI specification for policy-service. + name: OpenAPI x-cerberus: authentication: strategies: - - InternalJWT: {} -x-snyk-api-version: "2024-10-15" \ No newline at end of file + - InternalJWT: {} +x-snyk-api-version: "2024-10-15" diff --git a/pkg/local_workflows/ignore_workflow/ignore_workflow.go b/pkg/local_workflows/ignore_workflow/ignore_workflow.go index 5b745d55d..0813c53ce 100644 --- a/pkg/local_workflows/ignore_workflow/ignore_workflow.go +++ b/pkg/local_workflows/ignore_workflow/ignore_workflow.go @@ -232,7 +232,7 @@ func ignoreCreateWorkflowEntryPoint(invocationCtx workflow.InvocationContext, _ return nil, err } - payload := createPayload(repoUrl, branchName, expire, ignoreType, reason, findingsId) + payload := createPayload(invocationCtx, repoUrl, branchName, expire, ignoreType, reason, findingsId) response, err := sendCreateIgnore(invocationCtx, payload, orgUuid) if err != nil { @@ -300,11 +300,25 @@ func createIgnoreWorkflowData(id workflow.Identifier, config configuration.Confi return data, nil } -func createPayload(repoUrl string, branchName string, expire *time.Time, ignoreType string, reason string, findingsId string) policyApi.CreatePolicyPayload { +func createPayload(invocationCtx workflow.InvocationContext, repoUrl string, branchName string, expire *time.Time, ignoreType string, reason string, findingsId string) policyApi.CreatePolicyPayload { meta := policyApi.Meta{} meta["repo_url"] = repoUrl meta["branch_name"] = branchName + // Determine source based on RuntimeInfo + var source *policyApi.PolicyAttributesSource + runtimeInfo := invocationCtx.GetRuntimeInfo() + if runtimeInfo != nil { + runtimeName := runtimeInfo.GetName() + if runtimeName == "snyk-ls" { + ideSource := policyApi.Ide + source = &ideSource + } else if runtimeName == "snyk-cli" { + cliSource := policyApi.Cli + source = &cliSource + } + } + var payload policyApi.CreateOrgPolicyApplicationVndAPIPlusJSONRequestBody payload.Data.Meta = &meta payload.Data.Attributes.Action.Data = policyApi.PolicyActionIgnoreData{ @@ -324,6 +338,7 @@ func createPayload(repoUrl string, branchName string, expire *time.Time, ignoreT }, LogicalOperator: policyApi.And, } + payload.Data.Attributes.Source = source payload.Data.Type = policyApi.CreatePolicyPayloadDataTypePolicy return payload } diff --git a/pkg/local_workflows/ignore_workflow/ignore_workflow_test.go b/pkg/local_workflows/ignore_workflow/ignore_workflow_test.go index 05707e22a..49859d677 100644 --- a/pkg/local_workflows/ignore_workflow/ignore_workflow_test.go +++ b/pkg/local_workflows/ignore_workflow/ignore_workflow_test.go @@ -59,6 +59,7 @@ func setupMockIgnoreContext(t *testing.T, payload string, statusCode int) *mocks invocationContextMock := mocks.NewMockInvocationContext(ctrl) mockUserInterface := mocks.NewMockUserInterface(ctrl) mockEngine := mocks.NewMockEngine(ctrl) + mockRuntimeInfo := mocks.NewMockRuntimeInfo(ctrl) mockUserInterface.EXPECT().Output(gomock.Any()).Return(nil).AnyTimes() mockUserInterface.EXPECT().Input(gomock.Any()).Return("", nil).AnyTimes() @@ -81,7 +82,9 @@ func setupMockIgnoreContext(t *testing.T, payload string, statusCode int) *mocks invocationContextMock.EXPECT().GetEngine().Return(mockEngine).AnyTimes() invocationContextMock.EXPECT().GetUserInterface().Return(mockUserInterface).AnyTimes() invocationContextMock.EXPECT().GetWorkflowIdentifier().Return(workflow.NewWorkflowIdentifier(ignoreCreateWorkflowName)).AnyTimes() + invocationContextMock.EXPECT().GetRuntimeInfo().Return(mockRuntimeInfo).AnyTimes() networkAccessMock.EXPECT().GetHttpClient().Return(httpClient).AnyTimes() + mockRuntimeInfo.EXPECT().GetName().Return("snyk-cli").AnyTimes() mockData := []workflow.Data{workflow.NewData( workflow.NewTypeIdentifier(localworkflows.WORKFLOWID_WHOAMI, "whoami"), "text/plain", @@ -167,22 +170,61 @@ func Test_createPolicy(t *testing.T) { } func Test_createPayload(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + expireDate, err := time.Parse(time.DateOnly, "2025-01-01") assert.NoError(t, err) ignoreType := string(policyApi.TemporaryIgnore) reason := "Test reason" findingsId := uuid.New().String() - payload := createPayload(testRepoUrl, testBranchName, &expireDate, ignoreType, reason, findingsId) + t.Run("with CLI source (snyk-cli)", func(t *testing.T) { + mockInvocationCtx := mocks.NewMockInvocationContext(ctrl) + mockRuntimeInfo := mocks.NewMockRuntimeInfo(ctrl) + + mockInvocationCtx.EXPECT().GetRuntimeInfo().Return(mockRuntimeInfo) + mockRuntimeInfo.EXPECT().GetName().Return("snyk-cli") + + payload := createPayload(mockInvocationCtx, testRepoUrl, testBranchName, &expireDate, ignoreType, reason, findingsId) + + assert.Equal(t, policyApi.CreatePolicyPayloadDataTypePolicy, payload.Data.Type, "Should have correct payload type") + assert.Equal(t, ignoreType, string(payload.Data.Attributes.Action.Data.IgnoreType), "Should have correct ignore type") + assert.Equal(t, reason, *payload.Data.Attributes.Action.Data.Reason, "Should have correct reason") + assert.NotEmpty(t, payload.Data.Attributes.ConditionsGroup.Conditions, "Should have condition") + assert.Equal(t, policyApi.Snykassetfindingv1, payload.Data.Attributes.ConditionsGroup.Conditions[0].Field, "Should have correct findings ID") + assert.Equal(t, policyApi.Includes, payload.Data.Attributes.ConditionsGroup.Conditions[0].Operator, "Condition operation must be include") + assert.Equal(t, findingsId, payload.Data.Attributes.ConditionsGroup.Conditions[0].Value, "Should have correct findings ID") + assert.Equal(t, expireDate, *payload.Data.Attributes.Action.Data.Expires, "Should have correct expiration date") + + assert.NotNil(t, payload.Data.Attributes.Source, "Source should not be nil") + assert.Equal(t, policyApi.Cli, *payload.Data.Attributes.Source, "Source should be 'cli' for snyk-cli") + }) + + t.Run("with IDE source (snyk-ls)", func(t *testing.T) { + mockInvocationCtx := mocks.NewMockInvocationContext(ctrl) + mockRuntimeInfo := mocks.NewMockRuntimeInfo(ctrl) - assert.Equal(t, policyApi.CreatePolicyPayloadDataTypePolicy, payload.Data.Type, "Should have correct payload type") - assert.Equal(t, ignoreType, string(payload.Data.Attributes.Action.Data.IgnoreType), "Should have correct ignore type") - assert.Equal(t, reason, *payload.Data.Attributes.Action.Data.Reason, "Should have correct reason") - assert.NotEmpty(t, payload.Data.Attributes.ConditionsGroup.Conditions, "Should have condition") - assert.Equal(t, policyApi.Snykassetfindingv1, payload.Data.Attributes.ConditionsGroup.Conditions[0].Field, "Should have correct findings ID") - assert.Equal(t, policyApi.Includes, payload.Data.Attributes.ConditionsGroup.Conditions[0].Operator, "Condition operation must be include") - assert.Equal(t, findingsId, payload.Data.Attributes.ConditionsGroup.Conditions[0].Value, "Should have correct findings ID") - assert.Equal(t, expireDate, *payload.Data.Attributes.Action.Data.Expires, "Should have correct expiration date") + mockInvocationCtx.EXPECT().GetRuntimeInfo().Return(mockRuntimeInfo) + mockRuntimeInfo.EXPECT().GetName().Return("snyk-ls") + + payload := createPayload(mockInvocationCtx, testRepoUrl, testBranchName, &expireDate, ignoreType, reason, findingsId) + + assert.NotNil(t, payload.Data.Attributes.Source, "Source should not be nil") + assert.Equal(t, policyApi.Ide, *payload.Data.Attributes.Source, "Source should be 'ide' for snyk-ls") + }) + + t.Run("with unknown runtime name source is not set", func(t *testing.T) { + mockInvocationCtx := mocks.NewMockInvocationContext(ctrl) + mockRuntimeInfo := mocks.NewMockRuntimeInfo(ctrl) + + mockInvocationCtx.EXPECT().GetRuntimeInfo().Return(mockRuntimeInfo) + mockRuntimeInfo.EXPECT().GetName().Return("unknown-runtime") + + payload := createPayload(mockInvocationCtx, testRepoUrl, testBranchName, &expireDate, ignoreType, reason, findingsId) + + assert.Nil(t, payload.Data.Attributes.Source, "Source should be nil for unknown runtime names") + }) } func Test_ignoreCreateWorkflowEntryPoint(t *testing.T) { @@ -343,6 +385,7 @@ func setupInteractiveMockContext(t *testing.T, mockApiResponse string, mockApiSt invocationContextMock := mocks.NewMockInvocationContext(ctrl) mockUserInterface := mocks.NewMockUserInterface(ctrl) mockEngine := mocks.NewMockEngine(ctrl) + mockRuntimeInfo := mocks.NewMockRuntimeInfo(ctrl) mockUserInterface.EXPECT().Output(gomock.Any()).Return(nil).AnyTimes() @@ -360,7 +403,9 @@ func setupInteractiveMockContext(t *testing.T, mockApiResponse string, mockApiSt invocationContextMock.EXPECT().GetEngine().Return(mockEngine).AnyTimes() invocationContextMock.EXPECT().GetUserInterface().Return(mockUserInterface).AnyTimes() invocationContextMock.EXPECT().GetWorkflowIdentifier().Return(WORKFLOWID_IGNORE_CREATE).AnyTimes() + invocationContextMock.EXPECT().GetRuntimeInfo().Return(mockRuntimeInfo).AnyTimes() networkAccessMock.EXPECT().GetHttpClient().Return(httpClient).AnyTimes() + mockRuntimeInfo.EXPECT().GetName().Return("snyk-cli").AnyTimes() mockWhoamiData := []workflow.Data{workflow.NewData( workflow.NewTypeIdentifier(localworkflows.WORKFLOWID_WHOAMI, "whoami"),