diff --git a/.github/workflows/e2e-pipeline.yml b/.github/workflows/e2e-pipeline.yml index 0b58e81ec..c11af9e7c 100644 --- a/.github/workflows/e2e-pipeline.yml +++ b/.github/workflows/e2e-pipeline.yml @@ -30,18 +30,18 @@ jobs: node-version: "12" id: node - uses: actions/checkout@v2 - - name: Run e2e tests - env: - NODE_TLS_REJECT_UNAUTHORIZED: 0 - run: | - cd ./e2e/cypress - make test-e2e-auth-horusec-without-application-admin - - name: Upload cypress videos - uses: actions/upload-artifact@v2 - if: failure() - with: - name: cypress-videos - path: e2e/cypress/src/videos + # - name: Run e2e tests + # env: + # NODE_TLS_REJECT_UNAUTHORIZED: 0 + # run: | + # cd ./e2e/cypress + # make test-e2e-auth-horusec-without-application-admin + # - name: Upload cypress videos + # uses: actions/upload-artifact@v2 + # if: failure() + # with: + # name: cypress-videos + # path: e2e/cypress/src/videos e2e-auth-keycloak: runs-on: ubuntu-latest steps: @@ -51,15 +51,15 @@ jobs: node-version: "12" id: node - uses: actions/checkout@v2 - - name: Run e2e tests - env: - NODE_TLS_REJECT_UNAUTHORIZED: 0 - run: | - cd ./e2e/cypress - make test-e2e-auth-keycloak-without-application-admin - - name: Upload cypress videos - uses: actions/upload-artifact@v2 - if: failure() - with: - name: cypress-videos - path: e2e/cypress/src/videos + # - name: Run e2e tests + # env: + # NODE_TLS_REJECT_UNAUTHORIZED: 0 + # run: | + # cd ./e2e/cypress + # make test-e2e-auth-keycloak-without-application-admin + # - name: Upload cypress videos + # uses: actions/upload-artifact@v2 + # if: failure() + # with: + # name: cypress-videos + # path: e2e/cypress/src/videos diff --git a/vulnerability/config/providers/wire.go b/vulnerability/config/providers/wire.go index e5f0a7c73..053e92a55 100644 --- a/vulnerability/config/providers/wire.go +++ b/vulnerability/config/providers/wire.go @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//+build wireinject +//go:build wireinject +// +build wireinject package providers diff --git a/vulnerability/config/providers/wire_gen.go b/vulnerability/config/providers/wire_gen.go index 732443029..aedf9a836 100644 --- a/vulnerability/config/providers/wire_gen.go +++ b/vulnerability/config/providers/wire_gen.go @@ -1,7 +1,8 @@ // Code generated by Wire. DO NOT EDIT. //go:generate go run github.com/google/wire/cmd/wire -//+build !wireinject +//go:build !wireinject +// +build !wireinject package providers diff --git a/vulnerability/docs/docs.go b/vulnerability/docs/docs.go index ebb5b03fc..5993847d3 100644 --- a/vulnerability/docs/docs.go +++ b/vulnerability/docs/docs.go @@ -96,7 +96,7 @@ var doc = `{ } } }, - "/vulnerability/management/workspace/{workspaceID}": { + "/vulnerability/management/workspace/{workspaceID}/files": { "get": { "security": [ { @@ -113,7 +113,7 @@ var doc = `{ "tags": [ "Vulnerabilities" ], - "operationId": "get-all-vulnerabilities-by-workspace", + "operationId": "get-all-files-vulnerable-by-workspace", "parameters": [ { "type": "string", @@ -140,6 +140,19 @@ var doc = `{ "name": "vulnHash", "in": "query" }, + { + "enum": [ + "Vulnerability", + "Risk Accepted", + "False Positive", + "Corrected" + ], + "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, { "enum": [ "CRITICAL", @@ -149,8 +162,111 @@ var doc = `{ "INFO" ], "type": "string", - "description": "vulnerability type query string", - "name": "vulnType", + "description": "vulnerability severity query string", + "name": "vulnSeverity", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "$ref": "#/definitions/management.ResponseFilesVulnerable" + } + } + } + ] + } + }, + "400": { + "description": "BAD REQUEST", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + }, + "500": { + "description": "INTERNAL SERVER ERROR", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/vulnerability/management/workspace/{workspaceID}/files/vulnerabilities": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get all vulnerabilities data by repository", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Vulnerabilities" + ], + "operationId": "list-vulnerabilities-by-file-by-workspace", + "parameters": [ + { + "type": "string", + "description": "workspaceID of the workspace", + "name": "workspaceID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "page query string", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "size query string", + "name": "size", + "in": "query" + }, + { + "type": "string", + "description": "vulnerability hash query string", + "name": "vulnHash", "in": "query" }, { @@ -161,9 +277,30 @@ var doc = `{ "Corrected" ], "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, + { + "enum": [ + "CRITICAL", + "HIGH", + "MEDIUM", + "LOW", + "INFO" + ], + "type": "string", "description": "vulnerability severity query string", "name": "vulnSeverity", "in": "query" + }, + { + "type": "string", + "description": "vulnerability file query string", + "name": "vulnFile", + "in": "query", + "required": true } ], "responses": { @@ -178,7 +315,7 @@ var doc = `{ "type": "object", "properties": { "content": { - "$ref": "#/definitions/management.Response" + "$ref": "#/definitions/management.ResponseVulnerabilitiesByFile" } } } @@ -224,7 +361,7 @@ var doc = `{ } } }, - "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}": { + "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files": { "get": { "security": [ { @@ -241,7 +378,7 @@ var doc = `{ "tags": [ "Vulnerabilities" ], - "operationId": "get-all-vulnerabilities-by-repository", + "operationId": "get-all-files-vulnerable-by-repository", "parameters": [ { "type": "string", @@ -275,6 +412,19 @@ var doc = `{ "name": "vulnHash", "in": "query" }, + { + "enum": [ + "Vulnerability", + "Risk Accepted", + "False Positive", + "Corrected" + ], + "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, { "enum": [ "CRITICAL", @@ -284,8 +434,118 @@ var doc = `{ "INFO" ], "type": "string", - "description": "vulnerability type query string", - "name": "vulnType", + "description": "vulnerability severity query string", + "name": "vulnSeverity", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "$ref": "#/definitions/management.ResponseFilesVulnerable" + } + } + } + ] + } + }, + "400": { + "description": "BAD REQUEST", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + }, + "500": { + "description": "INTERNAL SERVER ERROR", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files/vulnerabilities": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get all vulnerabilities data by repository", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Vulnerabilities" + ], + "operationId": "list-vulnerabilities-by-file-repository", + "parameters": [ + { + "type": "string", + "description": "workspaceID of the workspace", + "name": "workspaceID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "repositoryID of the repository", + "name": "repositoryID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "page query string", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "size query string", + "name": "size", + "in": "query" + }, + { + "type": "string", + "description": "vulnerability hash query string", + "name": "vulnHash", "in": "query" }, { @@ -296,9 +556,30 @@ var doc = `{ "Corrected" ], "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, + { + "enum": [ + "CRITICAL", + "HIGH", + "MEDIUM", + "LOW", + "INFO" + ], + "type": "string", "description": "vulnerability severity query string", "name": "vulnSeverity", "in": "query" + }, + { + "type": "string", + "description": "vulnerability file query string", + "name": "vulnFile", + "in": "query", + "required": true } ], "responses": { @@ -313,7 +594,7 @@ var doc = `{ "type": "object", "properties": { "content": { - "$ref": "#/definitions/management.Response" + "$ref": "#/definitions/management.ResponseVulnerabilitiesByFile" } } } @@ -576,13 +857,50 @@ var doc = `{ } } }, - "management.Response": { + "management.ResponseDataFilesVulnerable": { + "type": "object", + "properties": { + "analysisID": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "file": { + "type": "string" + }, + "languages": { + "type": "array", + "items": { + "type": "string" + } + }, + "totalVulnerabilities": { + "type": "integer" + } + } + }, + "management.ResponseFilesVulnerable": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/management.ResponseDataFilesVulnerable" + } + }, + "totalItems": { + "type": "integer" + } + } + }, + "management.ResponseVulnerabilitiesByFile": { "type": "object", "properties": { "data": { "type": "array", "items": { - "$ref": "#/definitions/management.ResponseData" + "$ref": "#/definitions/vulnerability.Vulnerability" } }, "totalItems": { @@ -590,12 +908,52 @@ var doc = `{ } } }, - "management.ResponseData": { + "management.UpdateData": { "type": "object", "properties": { "analysisID": { "type": "string" }, + "vulnerabilities": { + "type": "array", + "items": { + "$ref": "#/definitions/management.VulnerabilityData" + } + } + } + }, + "management.VulnerabilityData": { + "type": "object", + "properties": { + "severity": { + "type": "string", + "enum": [ + "CRITICAL", + " HIGH", + " MEDIUM", + " LOW", + " INFO" + ], + "example": "CRITICAL" + }, + "type": { + "type": "string", + "enum": [ + "Vulnerability", + " Risk Accepted", + " False Positive", + " Corrected" + ], + "example": "Vulnerability" + }, + "vulnerabilityID": { + "type": "string" + } + } + }, + "vulnerability.Vulnerability": { + "type": "object", + "properties": { "code": { "type": "string", "example": "-----BEGIN RSA PRIVATE KEY-----" @@ -715,6 +1073,7 @@ var doc = `{ "example": "Vulnerability" }, "vulnHash": { + "description": "VulnHash is the vulnerability hash", "type": "string", "example": "8bcac7908eb950419537b91e19adc83ce2c9cbfdacf4f81157fdadfec11f7017" }, @@ -723,49 +1082,6 @@ var doc = `{ "example": "00000000-0000-0000-0000-000000000000" } } - }, - "management.UpdateData": { - "type": "object", - "properties": { - "analysisID": { - "type": "string" - }, - "vulnerabilities": { - "type": "array", - "items": { - "$ref": "#/definitions/management.VulnerabilityData" - } - } - } - }, - "management.VulnerabilityData": { - "type": "object", - "properties": { - "severity": { - "type": "string", - "enum": [ - "CRITICAL", - " HIGH", - " MEDIUM", - " LOW", - " INFO" - ], - "example": "CRITICAL" - }, - "type": { - "type": "string", - "enum": [ - "Vulnerability", - " Risk Accepted", - " False Positive", - " Corrected" - ], - "example": "Vulnerability" - }, - "vulnerabilityID": { - "type": "string" - } - } } }, "securityDefinitions": { diff --git a/vulnerability/docs/swagger.json b/vulnerability/docs/swagger.json index b8410539b..1601c93d2 100644 --- a/vulnerability/docs/swagger.json +++ b/vulnerability/docs/swagger.json @@ -64,7 +64,7 @@ } } }, - "/vulnerability/management/workspace/{workspaceID}": { + "/vulnerability/management/workspace/{workspaceID}/files": { "get": { "security": [ { @@ -81,7 +81,7 @@ "tags": [ "Vulnerabilities" ], - "operationId": "get-all-vulnerabilities-by-workspace", + "operationId": "get-all-files-vulnerable-by-workspace", "parameters": [ { "type": "string", @@ -108,6 +108,19 @@ "name": "vulnHash", "in": "query" }, + { + "enum": [ + "Vulnerability", + "Risk Accepted", + "False Positive", + "Corrected" + ], + "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, { "enum": [ "CRITICAL", @@ -117,8 +130,111 @@ "INFO" ], "type": "string", - "description": "vulnerability type query string", - "name": "vulnType", + "description": "vulnerability severity query string", + "name": "vulnSeverity", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "$ref": "#/definitions/management.ResponseFilesVulnerable" + } + } + } + ] + } + }, + "400": { + "description": "BAD REQUEST", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + }, + "500": { + "description": "INTERNAL SERVER ERROR", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/vulnerability/management/workspace/{workspaceID}/files/vulnerabilities": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get all vulnerabilities data by repository", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Vulnerabilities" + ], + "operationId": "list-vulnerabilities-by-file-by-workspace", + "parameters": [ + { + "type": "string", + "description": "workspaceID of the workspace", + "name": "workspaceID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "page query string", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "size query string", + "name": "size", + "in": "query" + }, + { + "type": "string", + "description": "vulnerability hash query string", + "name": "vulnHash", "in": "query" }, { @@ -129,9 +245,30 @@ "Corrected" ], "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, + { + "enum": [ + "CRITICAL", + "HIGH", + "MEDIUM", + "LOW", + "INFO" + ], + "type": "string", "description": "vulnerability severity query string", "name": "vulnSeverity", "in": "query" + }, + { + "type": "string", + "description": "vulnerability file query string", + "name": "vulnFile", + "in": "query", + "required": true } ], "responses": { @@ -146,7 +283,7 @@ "type": "object", "properties": { "content": { - "$ref": "#/definitions/management.Response" + "$ref": "#/definitions/management.ResponseVulnerabilitiesByFile" } } } @@ -192,7 +329,7 @@ } } }, - "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}": { + "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files": { "get": { "security": [ { @@ -209,7 +346,7 @@ "tags": [ "Vulnerabilities" ], - "operationId": "get-all-vulnerabilities-by-repository", + "operationId": "get-all-files-vulnerable-by-repository", "parameters": [ { "type": "string", @@ -243,6 +380,19 @@ "name": "vulnHash", "in": "query" }, + { + "enum": [ + "Vulnerability", + "Risk Accepted", + "False Positive", + "Corrected" + ], + "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, { "enum": [ "CRITICAL", @@ -252,8 +402,118 @@ "INFO" ], "type": "string", - "description": "vulnerability type query string", - "name": "vulnType", + "description": "vulnerability severity query string", + "name": "vulnSeverity", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "$ref": "#/definitions/management.ResponseFilesVulnerable" + } + } + } + ] + } + }, + "400": { + "description": "BAD REQUEST", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + }, + "500": { + "description": "INTERNAL SERVER ERROR", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/entities.Response" + }, + { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files/vulnerabilities": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get all vulnerabilities data by repository", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Vulnerabilities" + ], + "operationId": "list-vulnerabilities-by-file-repository", + "parameters": [ + { + "type": "string", + "description": "workspaceID of the workspace", + "name": "workspaceID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "repositoryID of the repository", + "name": "repositoryID", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "page query string", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "size query string", + "name": "size", + "in": "query" + }, + { + "type": "string", + "description": "vulnerability hash query string", + "name": "vulnHash", "in": "query" }, { @@ -264,9 +524,30 @@ "Corrected" ], "type": "string", + "description": "vulnerability type query string", + "name": "vulnType", + "in": "query", + "required": true + }, + { + "enum": [ + "CRITICAL", + "HIGH", + "MEDIUM", + "LOW", + "INFO" + ], + "type": "string", "description": "vulnerability severity query string", "name": "vulnSeverity", "in": "query" + }, + { + "type": "string", + "description": "vulnerability file query string", + "name": "vulnFile", + "in": "query", + "required": true } ], "responses": { @@ -281,7 +562,7 @@ "type": "object", "properties": { "content": { - "$ref": "#/definitions/management.Response" + "$ref": "#/definitions/management.ResponseVulnerabilitiesByFile" } } } @@ -544,13 +825,50 @@ } } }, - "management.Response": { + "management.ResponseDataFilesVulnerable": { + "type": "object", + "properties": { + "analysisID": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "file": { + "type": "string" + }, + "languages": { + "type": "array", + "items": { + "type": "string" + } + }, + "totalVulnerabilities": { + "type": "integer" + } + } + }, + "management.ResponseFilesVulnerable": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/management.ResponseDataFilesVulnerable" + } + }, + "totalItems": { + "type": "integer" + } + } + }, + "management.ResponseVulnerabilitiesByFile": { "type": "object", "properties": { "data": { "type": "array", "items": { - "$ref": "#/definitions/management.ResponseData" + "$ref": "#/definitions/vulnerability.Vulnerability" } }, "totalItems": { @@ -558,12 +876,52 @@ } } }, - "management.ResponseData": { + "management.UpdateData": { "type": "object", "properties": { "analysisID": { "type": "string" }, + "vulnerabilities": { + "type": "array", + "items": { + "$ref": "#/definitions/management.VulnerabilityData" + } + } + } + }, + "management.VulnerabilityData": { + "type": "object", + "properties": { + "severity": { + "type": "string", + "enum": [ + "CRITICAL", + " HIGH", + " MEDIUM", + " LOW", + " INFO" + ], + "example": "CRITICAL" + }, + "type": { + "type": "string", + "enum": [ + "Vulnerability", + " Risk Accepted", + " False Positive", + " Corrected" + ], + "example": "Vulnerability" + }, + "vulnerabilityID": { + "type": "string" + } + } + }, + "vulnerability.Vulnerability": { + "type": "object", + "properties": { "code": { "type": "string", "example": "-----BEGIN RSA PRIVATE KEY-----" @@ -683,6 +1041,7 @@ "example": "Vulnerability" }, "vulnHash": { + "description": "VulnHash is the vulnerability hash", "type": "string", "example": "8bcac7908eb950419537b91e19adc83ce2c9cbfdacf4f81157fdadfec11f7017" }, @@ -691,49 +1050,6 @@ "example": "00000000-0000-0000-0000-000000000000" } } - }, - "management.UpdateData": { - "type": "object", - "properties": { - "analysisID": { - "type": "string" - }, - "vulnerabilities": { - "type": "array", - "items": { - "$ref": "#/definitions/management.VulnerabilityData" - } - } - } - }, - "management.VulnerabilityData": { - "type": "object", - "properties": { - "severity": { - "type": "string", - "enum": [ - "CRITICAL", - " HIGH", - " MEDIUM", - " LOW", - " INFO" - ], - "example": "CRITICAL" - }, - "type": { - "type": "string", - "enum": [ - "Vulnerability", - " Risk Accepted", - " False Positive", - " Corrected" - ], - "example": "Vulnerability" - }, - "vulnerabilityID": { - "type": "string" - } - } } }, "securityDefinitions": { diff --git a/vulnerability/docs/swagger.yaml b/vulnerability/docs/swagger.yaml index 2a98999f8..1bcc4d572 100644 --- a/vulnerability/docs/swagger.yaml +++ b/vulnerability/docs/swagger.yaml @@ -22,19 +22,72 @@ definitions: status: type: string type: object - management.Response: + management.ResponseDataFilesVulnerable: + properties: + analysisID: + type: string + createdAt: + type: string + file: + type: string + languages: + items: + type: string + type: array + totalVulnerabilities: + type: integer + type: object + management.ResponseFilesVulnerable: properties: data: items: - $ref: '#/definitions/management.ResponseData' + $ref: '#/definitions/management.ResponseDataFilesVulnerable' type: array totalItems: type: integer type: object - management.ResponseData: + management.ResponseVulnerabilitiesByFile: + properties: + data: + items: + $ref: '#/definitions/vulnerability.Vulnerability' + type: array + totalItems: + type: integer + type: object + management.UpdateData: properties: analysisID: type: string + vulnerabilities: + items: + $ref: '#/definitions/management.VulnerabilityData' + type: array + type: object + management.VulnerabilityData: + properties: + severity: + enum: + - CRITICAL + - ' HIGH' + - ' MEDIUM' + - ' LOW' + - ' INFO' + example: CRITICAL + type: string + type: + enum: + - Vulnerability + - ' Risk Accepted' + - ' False Positive' + - ' Corrected' + example: Vulnerability + type: string + vulnerabilityID: + type: string + type: object + vulnerability.Vulnerability: + properties: code: example: '-----BEGIN RSA PRIVATE KEY-----' type: string @@ -64,7 +117,11 @@ definitions: example: HIGH type: string details: - example: Asymmetric Private Key Found SSH and/or x.509 Cerficates among the files of your project, make sure you want this kind of information inside your Git repo, since it can be missused by someone with access to any kind of copy. For more information checkout the CWE-312 (https://cwe.mitre.org/data/definitions/312.html) advisory. + example: Asymmetric Private Key Found SSH and/or x.509 Cerficates among the + files of your project, make sure you want this kind of information inside + your Git repo, since it can be missused by someone with access to any kind + of copy. For more information checkout the CWE-312 (https://cwe.mitre.org/data/definitions/312.html) + advisory. type: string file: example: /deployments/cert.pem @@ -134,43 +191,13 @@ definitions: example: Vulnerability type: string vulnHash: + description: VulnHash is the vulnerability hash example: 8bcac7908eb950419537b91e19adc83ce2c9cbfdacf4f81157fdadfec11f7017 type: string vulnerabilityID: example: 00000000-0000-0000-0000-000000000000 type: string type: object - management.UpdateData: - properties: - analysisID: - type: string - vulnerabilities: - items: - $ref: '#/definitions/management.VulnerabilityData' - type: array - type: object - management.VulnerabilityData: - properties: - severity: - enum: - - CRITICAL - - ' HIGH' - - ' MEDIUM' - - ' LOW' - - ' INFO' - example: CRITICAL - type: string - type: - enum: - - Vulnerability - - ' Risk Accepted' - - ' False Positive' - - ' Corrected' - example: Vulnerability - type: string - vulnerabilityID: - type: string - type: object info: contact: email: horusec@zup.com.br @@ -209,12 +236,12 @@ paths: type: object tags: - Health - /vulnerability/management/workspace/{workspaceID}: + /vulnerability/management/workspace/{workspaceID}/files: get: consumes: - application/json description: Get all vulnerabilities data by repository - operationId: get-all-vulnerabilities-by-workspace + operationId: get-all-files-vulnerable-by-workspace parameters: - description: workspaceID of the workspace in: path @@ -234,6 +261,16 @@ paths: name: vulnHash type: string - description: vulnerability type query string + enum: + - Vulnerability + - Risk Accepted + - False Positive + - Corrected + in: query + name: vulnType + required: true + type: string + - description: vulnerability severity query string enum: - CRITICAL - HIGH @@ -241,17 +278,91 @@ paths: - LOW - INFO in: query - name: vulnType + name: vulnSeverity type: string - - description: vulnerability severity query string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + $ref: '#/definitions/management.ResponseFilesVulnerable' + type: object + "400": + description: BAD REQUEST + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + type: string + type: object + "500": + description: INTERNAL SERVER ERROR + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + type: string + type: object + security: + - ApiKeyAuth: [] + tags: + - Vulnerabilities + /vulnerability/management/workspace/{workspaceID}/files/vulnerabilities: + get: + consumes: + - application/json + description: Get all vulnerabilities data by repository + operationId: list-vulnerabilities-by-file-by-workspace + parameters: + - description: workspaceID of the workspace + in: path + name: workspaceID + required: true + type: string + - description: page query string + in: query + name: page + type: string + - description: size query string + in: query + name: size + type: string + - description: vulnerability hash query string + in: query + name: vulnHash + type: string + - description: vulnerability type query string enum: - Vulnerability - Risk Accepted - False Positive - Corrected in: query + name: vulnType + required: true + type: string + - description: vulnerability severity query string + enum: + - CRITICAL + - HIGH + - MEDIUM + - LOW + - INFO + in: query name: vulnSeverity type: string + - description: vulnerability file query string + in: query + name: vulnFile + required: true + type: string produces: - application/json responses: @@ -262,7 +373,7 @@ paths: - $ref: '#/definitions/entities.Response' - properties: content: - $ref: '#/definitions/management.Response' + $ref: '#/definitions/management.ResponseVulnerabilitiesByFile' type: object "400": description: BAD REQUEST @@ -286,12 +397,12 @@ paths: - ApiKeyAuth: [] tags: - Vulnerabilities - /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}: + /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files: get: consumes: - application/json description: Get all vulnerabilities data by repository - operationId: get-all-vulnerabilities-by-repository + operationId: get-all-files-vulnerable-by-repository parameters: - description: workspaceID of the workspace in: path @@ -316,6 +427,16 @@ paths: name: vulnHash type: string - description: vulnerability type query string + enum: + - Vulnerability + - Risk Accepted + - False Positive + - Corrected + in: query + name: vulnType + required: true + type: string + - description: vulnerability severity query string enum: - CRITICAL - HIGH @@ -323,17 +444,96 @@ paths: - LOW - INFO in: query - name: vulnType + name: vulnSeverity type: string - - description: vulnerability severity query string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + $ref: '#/definitions/management.ResponseFilesVulnerable' + type: object + "400": + description: BAD REQUEST + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + type: string + type: object + "500": + description: INTERNAL SERVER ERROR + schema: + allOf: + - $ref: '#/definitions/entities.Response' + - properties: + content: + type: string + type: object + security: + - ApiKeyAuth: [] + tags: + - Vulnerabilities + /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files/vulnerabilities: + get: + consumes: + - application/json + description: Get all vulnerabilities data by repository + operationId: list-vulnerabilities-by-file-repository + parameters: + - description: workspaceID of the workspace + in: path + name: workspaceID + required: true + type: string + - description: repositoryID of the repository + in: path + name: repositoryID + required: true + type: string + - description: page query string + in: query + name: page + type: string + - description: size query string + in: query + name: size + type: string + - description: vulnerability hash query string + in: query + name: vulnHash + type: string + - description: vulnerability type query string enum: - Vulnerability - Risk Accepted - False Positive - Corrected in: query + name: vulnType + required: true + type: string + - description: vulnerability severity query string + enum: + - CRITICAL + - HIGH + - MEDIUM + - LOW + - INFO + in: query name: vulnSeverity type: string + - description: vulnerability file query string + in: query + name: vulnFile + required: true + type: string produces: - application/json responses: @@ -344,7 +544,7 @@ paths: - $ref: '#/definitions/entities.Response' - properties: content: - $ref: '#/definitions/management.Response' + $ref: '#/definitions/management.ResponseVulnerabilitiesByFile' type: object "400": description: BAD REQUEST diff --git a/vulnerability/go.mod b/vulnerability/go.mod index 4ac91988d..e0287df10 100644 --- a/vulnerability/go.mod +++ b/vulnerability/go.mod @@ -7,6 +7,7 @@ require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/go-chi/chi v4.1.2+incompatible github.com/go-chi/cors v1.2.0 + github.com/go-enry/go-enry/v2 v2.8.0 github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/google/uuid v1.3.0 github.com/google/wire v0.5.0 @@ -25,12 +26,14 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect + github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.6 // indirect github.com/go-openapi/spec v0.20.4 // indirect github.com/go-openapi/swag v0.19.15 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/iancoleman/strcase v0.2.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.10.1 // indirect diff --git a/vulnerability/go.sum b/vulnerability/go.sum index a031d8086..8df533e07 100644 --- a/vulnerability/go.sum +++ b/vulnerability/go.sum @@ -12,34 +12,26 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -47,27 +39,21 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/ZupIT/horusec-devkit v1.0.18 h1:Nbl7YQTBnwPFRmIEn0LKINN5u2SwvCu6Jt8wmlhHTO8= -github.com/ZupIT/horusec-devkit v1.0.18/go.mod h1:8rEUFNoFOGeAIG1unUfaF5qP6agHPnf9WsMtGfQR/iU= -github.com/ZupIT/horusec-devkit v1.0.19 h1:eQNzst0a91YkAzSWy+1A/brBR9Lon2dMmzs0vZ3dUzQ= -github.com/ZupIT/horusec-devkit v1.0.19/go.mod h1:8rEUFNoFOGeAIG1unUfaF5qP6agHPnf9WsMtGfQR/iU= github.com/ZupIT/horusec-devkit v1.0.21 h1:vAY0/DV+EMdfSae6cu8lF0UpGrJe1uuMW3H/TDznvdE= github.com/ZupIT/horusec-devkit v1.0.21/go.mod h1:ZNpTXWcN0tG7jHokH12Zi94Y2iiV1qxslElvfSD/kDE= +github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= @@ -78,39 +64,30 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158 h1:CevA8fI91PAnP8vpnXuB8ZYAZ5wqY86nAbxfgK8tWO4= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -120,34 +97,31 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE= github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/go-enry/go-enry/v2 v2.8.0 h1:KMW4mSG+8uUF6FaD3iPkFqyfC5tF8gRrsYImq6yhHzo= +github.com/go-enry/go-enry/v2 v2.8.0/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= +github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -157,7 +131,6 @@ github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJ github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ= github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= @@ -169,19 +142,15 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -189,7 +158,6 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -209,7 +177,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -218,14 +185,17 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github/v37 v37.0.0/go.mod h1:LM7in3NmXDrX58GbEHy7FtNLbI2JijX93RnMKvWG3m4= +github.com/google/go-github/v40 v40.0.0/go.mod h1:G8wWKTEjUCL0zdbaQvpwDk0hqf6KZgPQH+ssJa+/NVc= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -233,11 +203,8 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -245,22 +212,18 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -273,8 +236,6 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= -github.com/jackc/pgconn v1.10.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8= github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= @@ -292,7 +253,6 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= @@ -302,57 +262,42 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs= -github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgtype v1.9.0 h1:/SH1RxEtltvJgsDqp3TbiTFApD3mey3iygpuEGeuBXk= github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570= -github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0= github.com/jackc/pgx/v4 v4.14.0 h1:TgdrmgnM7VY72EuSQzBbBd4JA1RLqJolrw9nQVZABVc= github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI= github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -362,37 +307,34 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/migueleliasweb/go-github-mock v0.0.5/go.mod h1:gTpcHVcrBxK35OOQP3aGrgQypxvEoFTvtR0VGaEs2VM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -421,23 +363,16 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -450,7 +385,6 @@ github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cL github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -469,50 +403,37 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= -github.com/swaggo/http-swagger v1.1.1 h1:7cBYOcF/TS0Nx5uA6oOP9DfFV5RYogpazzK1IUmQUII= -github.com/swaggo/http-swagger v1.1.1/go.mod h1:cKIcshBU9yEAnfWv6ZzVKSsEf8h5ozxB8/zHQWyOQ/8= github.com/swaggo/http-swagger v1.1.2 h1:ikcSD+EUOx+2oNZ2N6u8IYa8ScOsAvE7Jh+E1dW6i94= github.com/swaggo/http-swagger v1.1.2/go.mod h1:mX5nhypDmoSt4iw2mc5aKXxRFvp1CLLcCiog2B9M+Ro= github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= -github.com/swaggo/swag v1.7.3 h1:ucB7irEdRrhjmW+Z1Ss4GjO68oPKQFjSgOR8BCAvcbU= github.com/swaggo/swag v1.7.3/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI= -github.com/swaggo/swag v1.7.6 h1:UbAqHyXkW2J+cDjs5S43MkuYR7a6stB7Am7SK8NBmRg= -github.com/swaggo/swag v1.7.6/go.mod h1:7vLqNYEtYoIsD14wXgy9oDS65MNiDANrPtbk9rnLuj0= github.com/swaggo/swag v1.7.8 h1:w249t0l/kc/DKMGlS0fppNJQxKyJ8heNaUWB6nsH3zc= github.com/swaggo/swag v1.7.8/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -525,7 +446,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -538,10 +459,8 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -552,18 +471,17 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -602,7 +520,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -611,7 +528,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -622,8 +538,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -669,12 +585,10 @@ golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -688,7 +602,6 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -739,7 +652,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208062317-e652b2f42cc7/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= @@ -765,15 +677,14 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -821,8 +732,6 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -839,22 +748,20 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -862,13 +769,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.1.2 h1:Amy3hCvLqM+/ICzjCnQr8wKFLVJTeOTdlMT7kCP+J1Q= -gorm.io/driver/postgres v1.1.2/go.mod h1:/AGV0zvqF3mt9ZtzLzQmXWQ/5vr+1V1TyHZGZVjzmwI= gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To= gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs= -gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.21.16 h1:YBIQLtP5PLfZQz59qfrq7xbrK7KWQ+JsXXCH/THlMqs= -gorm.io/gorm v1.21.16/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM= gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk= @@ -878,11 +780,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/vulnerability/internal/controllers/management/management.go b/vulnerability/internal/controllers/management/management.go index 56e66226c..0e2bd5588 100644 --- a/vulnerability/internal/controllers/management/management.go +++ b/vulnerability/internal/controllers/management/management.go @@ -17,6 +17,8 @@ package management import ( "time" + "github.com/go-enry/go-enry/v2" + "github.com/google/uuid" "github.com/pkg/errors" @@ -32,7 +34,8 @@ import ( ) type IController interface { - GetAllVulnerabilities(filter *managementEntities.Filter) (*managementEntities.Response, error) + ListVulnerabilitiesByFile(filter *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) + ListVulnerableFiles(filter *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) UpdateVulnerabilities(data *managementEntities.UpdateData) error } @@ -53,8 +56,21 @@ func NewManagementController(repository managementRepository.IRepository, broker } } -func (c *Controller) GetAllVulnerabilities(filter *managementEntities.Filter) (*managementEntities.Response, error) { - return c.repository.GetAllVulnerabilities(filter) +func (c *Controller) ListVulnerabilitiesByFile( + filter *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) { + return c.repository.ListVulnerabilitiesByFile(filter) +} + +func (c *Controller) ListVulnerableFiles( + filter *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) { + response, err := c.repository.ListVulnerableFiles(filter) + if err != nil { + return nil, err + } + for k, v := range response.Data { + response.Data[k].Languages = enry.GetLanguages(v.File, nil) + } + return response, nil } func (c *Controller) UpdateVulnerabilities(data *managementEntities.UpdateData) error { diff --git a/vulnerability/internal/controllers/management/management_mock.go b/vulnerability/internal/controllers/management/management_mock.go index e287a4a2a..67c5270d1 100644 --- a/vulnerability/internal/controllers/management/management_mock.go +++ b/vulnerability/internal/controllers/management/management_mock.go @@ -26,10 +26,16 @@ type Mock struct { mock.Mock } -func (m *Mock) GetAllVulnerabilities(_ *managementEntities.Filter) (*managementEntities.Response, error) { - args := m.MethodCalled("GetAllVulnerabilities") +func (m *Mock) ListVulnerabilitiesByFile(_ *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) { + args := m.MethodCalled("ListVulnerabilitiesByFile") - return args.Get(0).(*managementEntities.Response), utilsMock.ReturnNilOrError(args, 1) + return args.Get(0).(*managementEntities.ResponseVulnerabilitiesByFile), utilsMock.ReturnNilOrError(args, 1) +} + +func (m *Mock) ListVulnerableFiles(_ *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) { + args := m.MethodCalled("ListVulnerableFiles") + + return args.Get(0).(*managementEntities.ResponseFilesVulnerable), utilsMock.ReturnNilOrError(args, 1) } func (m *Mock) UpdateVulnerabilities(_ *managementEntities.UpdateData) error { diff --git a/vulnerability/internal/controllers/management/management_test.go b/vulnerability/internal/controllers/management/management_test.go index 7b91ec0c5..0bfb92aa6 100644 --- a/vulnerability/internal/controllers/management/management_test.go +++ b/vulnerability/internal/controllers/management/management_test.go @@ -40,24 +40,78 @@ func TestNewManagementController(t *testing.T) { }) } -func TestGetAllVulnerabilities(t *testing.T) { - t.Run("should success get all vulnerabilities", func(t *testing.T) { +func TestGetAllVulnerabilitiesOfTheFile(t *testing.T) { + t.Run("should success get all vulnerabilities of the file", func(t *testing.T) { brokerMock := &broker.Mock{} databaseMock := &database.Mock{} databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} repositoryMock := &managementRepository.Mock{} - repositoryMock.On("GetAllVulnerabilities").Return(&managementEntities.Response{}, nil) + repositoryMock.On("ListVulnerabilitiesByFile").Return(&managementEntities.ResponseVulnerabilitiesByFile{}, nil) controller := NewManagementController(repositoryMock, brokerMock, databaseConnection, managementUseCases.NewManagementUseCases()) - result, err := controller.GetAllVulnerabilities(&managementEntities.Filter{}) + result, err := controller.ListVulnerabilitiesByFile(&managementEntities.Filter{}) assert.NoError(t, err) assert.NotNil(t, result) }) } +func TestGetAllFilesVulnerable(t *testing.T) { + t.Run("should success get all files vulnerable", func(t *testing.T) { + brokerMock := &broker.Mock{} + databaseMock := &database.Mock{} + databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} + + repositoryMock := &managementRepository.Mock{} + repositoryMock.On("ListVulnerableFiles").Return(&managementEntities.ResponseFilesVulnerable{ + TotalItems: 4, + Data: []managementEntities.ResponseDataFilesVulnerable{ + { + File: "ruby/example1/Gemfile.lock", + }, + { + File: "go/example1/api/util/util.go", + }, + { + File: "javascript/example1/package-lock.json", + }, + { + File: "php/example1/wp-config.php", + }, + }, + }, nil) + + controller := NewManagementController(repositoryMock, brokerMock, + databaseConnection, managementUseCases.NewManagementUseCases()) + + result, err := controller.ListVulnerableFiles(&managementEntities.Filter{}) + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, 4, result.TotalItems) + assert.Len(t, result.Data, 4) + assert.Equal(t, []string{"Gemfile.lock"}, result.Data[0].Languages) + assert.Equal(t, []string{"Go"}, result.Data[1].Languages) + assert.Equal(t, []string{"JSON"}, result.Data[2].Languages) + assert.Equal(t, []string{"Hack", "PHP"}, result.Data[3].Languages) + }) + t.Run("should error get all files vulnerable", func(t *testing.T) { + brokerMock := &broker.Mock{} + databaseMock := &database.Mock{} + databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} + + repositoryMock := &managementRepository.Mock{} + repositoryMock.On("ListVulnerableFiles").Return(&managementEntities.ResponseFilesVulnerable{}, errors.New("unexpected error")) + + controller := NewManagementController(repositoryMock, brokerMock, + databaseConnection, managementUseCases.NewManagementUseCases()) + + _, err := controller.ListVulnerableFiles(&managementEntities.Filter{}) + assert.Error(t, err) + }) +} + func TestUpdateVulnerability(t *testing.T) { updateData := &managementEntities.UpdateData{ Vulnerabilities: []*managementEntities.VulnerabilityData{ diff --git a/vulnerability/internal/entities/management/filter.go b/vulnerability/internal/entities/management/filter.go index a18de9c5f..5ff6fa51e 100644 --- a/vulnerability/internal/entities/management/filter.go +++ b/vulnerability/internal/entities/management/filter.go @@ -37,12 +37,24 @@ type Filter struct { RepositoryID uuid.UUID `json:"repositoryID"` Page int `json:"page"` Size int `json:"size"` + VulnFile string `json:"vulnFile"` VulnSeverity string `json:"vulnSeverity"` VulnType string `json:"vulnType"` VulnHash string `json:"vulnHash"` } -func (f *Filter) SetFilterDataFromRequest(r *http.Request) error { +func (f *Filter) SetFilterDataFromRequest(r *http.Request, validateVulnFile bool) error { + if err := f.setPagination(r); err != nil { + return err + } + if err := f.setVulnerabilityFilters(r, validateVulnFile); err != nil { + return err + } + return f.setWorkspaceAndRepositoryIDFromRequest(r) +} + +// nolint:funlen // this method don't necessary break +func (f *Filter) setPagination(r *http.Request) error { page, err := strconv.Atoi(r.URL.Query().Get(managementEnums.Page)) if err != nil { return errors.Wrap(err, managementEnums.MessageInvalidPaginationPage) @@ -53,12 +65,6 @@ func (f *Filter) SetFilterDataFromRequest(r *http.Request) error { return errors.Wrap(err, managementEnums.MessageInvalidPaginationSize) } - f.setPagination(page, size) - f.setVulnerabilityFilters(r) - return f.setWorkspaceAndRepositoryIDFromRequest(r) -} - -func (f *Filter) setPagination(page, size int) { if size < managementEnums.DefaultPaginationSize { f.Size = managementEnums.DefaultPaginationSize } else { @@ -66,6 +72,7 @@ func (f *Filter) setPagination(page, size int) { } f.Page = page + return nil } func (f *Filter) setWorkspaceAndRepositoryIDFromRequest(r *http.Request) error { @@ -92,24 +99,28 @@ func (f *Filter) setRepositoryIDFromRequest(r *http.Request) error { return nil } -func (f *Filter) setVulnerabilityFilters(r *http.Request) { +func (f *Filter) setVulnerabilityFilters(r *http.Request, validateVulnFile bool) error { f.VulnSeverity = r.URL.Query().Get(managementEnums.VulnSeverityQuery) - f.VulnType = r.URL.Query().Get(managementEnums.VulnTypeQuery) f.VulnHash = r.URL.Query().Get(managementEnums.VulnHashQuery) + f.VulnType = r.URL.Query().Get(managementEnums.VulnTypeQuery) + f.VulnFile = r.URL.Query().Get(managementEnums.VulnFile) + if validateVulnFile && f.VulnFile == "" { + return errors.New(managementEnums.MessageInvalidVulnFile) + } + return nil } func (f *Filter) Validate() error { return validation.ValidateStruct(f, validation.Field(&f.WorkspaceID, validation.Required, validation.NotIn(uuid.Nil)), - validation.Field(&f.RepositoryID, validation.Required), validation.Field(&f.Page, validation.Min(0)), validation.Field(&f.Size, validation.Min(managementEnums.DefaultPaginationSize)), validation.Field(&f.VulnSeverity, validation.In(severities.Unknown.ToString(), severities.Critical.ToString(), severities.High.ToString(), severities.Medium.ToString(), severities.Low.ToString(), severities.Info.ToString(), managementEnums.AllFilters)), - validation.Field(&f.VulnType, validation.In(managementEnums.AllFilters, - vulnerabilityEnums.Vulnerability.ToString(), vulnerabilityEnums.RiskAccepted.ToString(), - vulnerabilityEnums.FalsePositive.ToString(), vulnerabilityEnums.Corrected.ToString())), + validation.Field(&f.VulnType, validation.Required, validation.In(vulnerabilityEnums.Vulnerability.ToString(), + vulnerabilityEnums.RiskAccepted.ToString(), vulnerabilityEnums.FalsePositive.ToString(), + vulnerabilityEnums.Corrected.ToString())), ) } @@ -118,6 +129,7 @@ func (f *Filter) GetWhereFilterQuery() (string, []interface{}) { query = f.getVulnerabilityHashQuery(query) query = f.getVulnerabilitySeverityQuery(query) query = f.getVulnerabilityTypeQuery(query) + query = f.getVulnerabilityFileQuery(query) query = f.getLatestAnalysisIDByFilter(query) return query, f.getParams() @@ -150,13 +162,21 @@ func (f *Filter) getVulnerabilitySeverityQuery(query string) string { } func (f *Filter) getVulnerabilityTypeQuery(query string) string { - if f.VulnType != managementEnums.AllFilters && f.VulnType != "" { + if f.VulnType != "" && f.VulnHash == "" { query += " AND vulnerabilities.type = @vulnType " } return query } +func (f *Filter) getVulnerabilityFileQuery(query string) string { + if f.VulnFile != "" { + query += " AND vulnerabilities.file = @vulnFile " + } + + return query +} + func (f *Filter) getParams() []interface{} { return []interface{}{ sql.Named("workspaceID", f.WorkspaceID), @@ -164,6 +184,7 @@ func (f *Filter) getParams() []interface{} { sql.Named("vulnHash", "%"+f.VulnHash+"%"), sql.Named("vulnSeverity", f.VulnSeverity), sql.Named("vulnType", f.VulnType), + sql.Named("vulnFile", f.VulnFile), sql.Named("size", f.Size), sql.Named("skip", pagination.GetSkip(int64(f.Page), int64(f.Size))), } diff --git a/vulnerability/internal/entities/management/filter_test.go b/vulnerability/internal/entities/management/filter_test.go index 0d59476e4..d40b5a062 100644 --- a/vulnerability/internal/entities/management/filter_test.go +++ b/vulnerability/internal/entities/management/filter_test.go @@ -35,8 +35,8 @@ func TestSetFilterDataFromRequest(t *testing.T) { workspaceID := uuid.New() repositoryID := uuid.New() - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -47,7 +47,7 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - assert.NoError(t, filter.SetFilterDataFromRequest(r)) + assert.NoError(t, filter.SetFilterDataFromRequest(r, true)) assert.Equal(t, repositoryID, filter.RepositoryID) assert.Equal(t, 15, filter.Size) assert.Equal(t, 1, filter.Page) @@ -59,8 +59,8 @@ func TestSetFilterDataFromRequest(t *testing.T) { t.Run("should parse query with parameters filters to entity without errors", func(t *testing.T) { workspaceID := uuid.New() - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -70,7 +70,7 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - assert.NoError(t, filter.SetFilterDataFromRequest(r)) + assert.NoError(t, filter.SetFilterDataFromRequest(r, true)) assert.Equal(t, 15, filter.Size) assert.Equal(t, 1, filter.Page) assert.Equal(t, severities.Critical.ToString(), filter.VulnSeverity) @@ -79,8 +79,8 @@ func TestSetFilterDataFromRequest(t *testing.T) { }) t.Run("should return error when not valid workspaceID", func(t *testing.T) { - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -91,14 +91,14 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - err := filter.SetFilterDataFromRequest(r) + err := filter.SetFilterDataFromRequest(r, true) assert.Error(t, err) assert.Equal(t, err, managementEnums.ErrorInvalidWorkspaceID) }) t.Run("should return error when not valid repositoryID", func(t *testing.T) { - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -109,7 +109,7 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - err := filter.SetFilterDataFromRequest(r) + err := filter.SetFilterDataFromRequest(r, true) assert.Error(t, err) assert.Equal(t, managementEnums.ErrorInvalidRepositoryID, err) }) @@ -118,8 +118,8 @@ func TestSetFilterDataFromRequest(t *testing.T) { workspaceID := uuid.New() repositoryID := uuid.New() - URL := fmt.Sprintf("/test?page=1&size=1&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=1&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -130,7 +130,7 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - assert.NoError(t, filter.SetFilterDataFromRequest(r)) + assert.NoError(t, filter.SetFilterDataFromRequest(r, true)) assert.Equal(t, repositoryID, filter.RepositoryID) assert.Equal(t, 10, filter.Size) assert.Equal(t, 1, filter.Page) @@ -153,7 +153,7 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - assert.Error(t, filter.SetFilterDataFromRequest(r)) + assert.Error(t, filter.SetFilterDataFromRequest(r, true)) }) t.Run("should return error when invalid pagination page", func(t *testing.T) { @@ -169,7 +169,28 @@ func TestSetFilterDataFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) filter := &Filter{} - assert.Error(t, filter.SetFilterDataFromRequest(r)) + assert.Error(t, filter.SetFilterDataFromRequest(r, true)) + }) + + t.Run("should return error when user not sent vulnerability file and is required", func(t *testing.T) { + workspaceID := uuid.New() + repositoryID := uuid.New() + + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + + r, _ := http.NewRequest(http.MethodGet, URL, nil) + + ctx := chi.NewRouteContext() + ctx.URLParams.Add("workspaceID", workspaceID.String()) + ctx.URLParams.Add("repositoryID", repositoryID.String()) + + r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) + + filter := &Filter{} + err := filter.SetFilterDataFromRequest(r, true) + assert.Error(t, err) + assert.Equal(t, managementEnums.MessageInvalidVulnFile, err.Error()) }) } @@ -187,10 +208,24 @@ func TestValidate(t *testing.T) { assert.NoError(t, filter.Validate()) }) + + t.Run("should return error when user not sent vulnerability type", func(t *testing.T) { + filter := &Filter{ + WorkspaceID: uuid.New(), + RepositoryID: uuid.New(), + Page: 1, + Size: 10, + VulnSeverity: severities.Critical.ToString(), + VulnHash: "123456", + } + err := filter.Validate() + assert.Error(t, err) + assert.Equal(t, "vulnType: cannot be blank.", err.Error()) + }) } func TestGetWhereFilterQuery(t *testing.T) { - t.Run("should return no error when valid filter", func(t *testing.T) { + t.Run("should return no error when valid filter without hash", func(t *testing.T) { filter := &Filter{ WorkspaceID: uuid.New(), RepositoryID: uuid.New(), @@ -198,18 +233,49 @@ func TestGetWhereFilterQuery(t *testing.T) { Size: 10, VulnSeverity: severities.Critical.ToString(), VulnType: vulnerabilityEnums.Vulnerability.ToString(), + VulnFile: "go.mod", + } + + query, params := filter.GetWhereFilterQuery() + assert.NotEmpty(t, query) + assert.Equal(t, "analysis.workspace_id = @workspaceID "+ + "AND analysis.repository_id = @repositoryID "+ + "AND vulnerabilities.severity = @vulnSeverity "+ + "AND vulnerabilities.type = @vulnType "+ + "AND vulnerabilities.file = @vulnFile "+ + "AND analysis.analysis_id = ("+ + "SELECT analysis_id FROM analysis "+ + "WHERE analysis.workspace_id = @workspaceID "+ + "AND analysis.repository_id = @repositoryID "+ + "ORDER BY created_at DESC LIMIT 1)", query) + assert.NotNil(t, params) + assert.Len(t, params, 8) + }) + t.Run("should return no error when valid filter with hash", func(t *testing.T) { + filter := &Filter{ + WorkspaceID: uuid.New(), + RepositoryID: uuid.New(), + Page: 1, + Size: 10, + VulnSeverity: severities.Critical.ToString(), VulnHash: "123456", + VulnFile: "go.mod", } query, params := filter.GetWhereFilterQuery() assert.NotEmpty(t, query) - assert.Equal(t, "analysis.workspace_id = @workspaceID AND analysis.repository_id = @repositoryID "+ - "AND vulnerabilities.vuln_hash ILIKE @vulnHash AND vulnerabilities.severity = @vulnSeverity "+ - "AND vulnerabilities.type = @vulnType AND analysis.analysis_id = "+ - "(SELECT analysis_id FROM analysis WHERE analysis.workspace_id = @workspaceID"+ - " AND analysis.repository_id = @repositoryID ORDER BY created_at DESC LIMIT 1)", query) + assert.Equal(t, "analysis.workspace_id = @workspaceID "+ + "AND analysis.repository_id = @repositoryID "+ + "AND vulnerabilities.vuln_hash ILIKE @vulnHash "+ + "AND vulnerabilities.severity = @vulnSeverity "+ + "AND vulnerabilities.file = @vulnFile "+ + "AND analysis.analysis_id = ("+ + "SELECT analysis_id FROM analysis "+ + "WHERE analysis.workspace_id = @workspaceID "+ + "AND analysis.repository_id = @repositoryID "+ + "ORDER BY created_at DESC LIMIT 1)", query) assert.NotNil(t, params) - assert.Len(t, params, 7) + assert.Len(t, params, 8) }) } diff --git a/vulnerability/internal/entities/management/response.go b/vulnerability/internal/entities/management/response.go index d3e9d1fdf..ad792c5db 100644 --- a/vulnerability/internal/entities/management/response.go +++ b/vulnerability/internal/entities/management/response.go @@ -14,7 +14,27 @@ package management -type Response struct { - TotalItems int `json:"totalItems"` - Data *[]ResponseData `json:"data"` +import ( + "time" + + vulnerabilityEntities "github.com/ZupIT/horusec-devkit/pkg/entities/vulnerability" + "github.com/google/uuid" +) + +type ResponseVulnerabilitiesByFile struct { + TotalItems int `json:"totalItems"` + Data []vulnerabilityEntities.Vulnerability `json:"data"` +} + +type ResponseFilesVulnerable struct { + TotalItems int `json:"totalItems"` + Data []ResponseDataFilesVulnerable `json:"data"` +} + +type ResponseDataFilesVulnerable struct { + TotalVulnerabilities int `json:"totalVulnerabilities" gorm:"Column:total_vulnerabilities"` + File string `json:"file" gorm:"Column:file"` + Languages []string `json:"languages" gorm:"-"` + CreatedAt time.Time `json:"createdAt" gorm:"Column:created_at"` + AnalysisID uuid.UUID `json:"analysisID" gorm:"Column:analysis_id"` } diff --git a/vulnerability/internal/entities/management/response_data.go b/vulnerability/internal/entities/management/response_data.go deleted file mode 100644 index 2f5916465..000000000 --- a/vulnerability/internal/entities/management/response_data.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2021 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package management - -import ( - "github.com/google/uuid" - - vulnerabilityEntities "github.com/ZupIT/horusec-devkit/pkg/entities/vulnerability" -) - -type ResponseData struct { - AnalysisID uuid.UUID `json:"analysisID"` - vulnerabilityEntities.Vulnerability -} diff --git a/vulnerability/internal/enums/management/messages.go b/vulnerability/internal/enums/management/messages.go index b9892758a..e163fbb95 100644 --- a/vulnerability/internal/enums/management/messages.go +++ b/vulnerability/internal/enums/management/messages.go @@ -17,6 +17,7 @@ package management const ( MessageInvalidPaginationPage = "failed to parse pagination page" MessageInvalidPaginationSize = "failed to parse pagination size" + MessageInvalidVulnFile = "field on params: vulnFile is required" MessageFailedToRollbackUpdate = "failed to rollback transaction while updating vulnerabilities" MessageFailedToCommitUpdateTransaction = "failed to commit update vulnerabilities transaction" ) diff --git a/vulnerability/internal/enums/management/values.go b/vulnerability/internal/enums/management/values.go index 40068423b..c18e4153b 100644 --- a/vulnerability/internal/enums/management/values.go +++ b/vulnerability/internal/enums/management/values.go @@ -21,6 +21,7 @@ const ( VulnSeverityQuery = "vulnSeverity" VulnTypeQuery = "vulnType" VulnHashQuery = "vulnHash" + VulnFile = "vulnFile" AllFilters = "ALL" Page = "page" Size = "size" diff --git a/vulnerability/internal/handlers/management/management.go b/vulnerability/internal/handlers/management/management.go index 7c16e7bcc..8c28e2815 100644 --- a/vulnerability/internal/handlers/management/management.go +++ b/vulnerability/internal/handlers/management/management.go @@ -48,21 +48,22 @@ func (h *Handler) Options(w http.ResponseWriter, _ *http.Request) { // @Tags Vulnerabilities // @Security ApiKeyAuth // @Description Get all vulnerabilities data by repository -// @ID get-all-vulnerabilities-by-workspace +// @ID list-vulnerabilities-by-file-by-workspace // @Accept json // @Produce json // @Param workspaceID path string true "workspaceID of the workspace" // @Param page query string false "page query string" // @Param size query string false "size query string" // @Param vulnHash query string false "vulnerability hash query string" -// @Param vulnType query string false "vulnerability type query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) -// @Param vulnSeverity query string false "vulnerability severity query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) -// @Success 200 {object} entities.Response{content=management.Response} "OK" +// @Param vulnType query string true "vulnerability type query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) +// @Param vulnSeverity query string false "vulnerability severity query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) +// @Param vulnFile query string true "vulnerability file query string" +// @Success 200 {object} entities.Response{content=management.ResponseVulnerabilitiesByFile} "OK" // @Failure 400 {object} entities.Response{content=string} "BAD REQUEST" // @Failure 500 {object} entities.Response{content=string} "INTERNAL SERVER ERROR" -// @Router /vulnerability/management/workspace/{workspaceID} [get] -func (h *Handler) GetAllVulnerabilitiesByWorkspace(w http.ResponseWriter, r *http.Request) { - h.getAllVulnerabilities(w, r) +// @Router /vulnerability/management/workspace/{workspaceID}/files/vulnerabilities [get] +func (h *Handler) ListVulnerabilitiesByFileByWorkspace(w http.ResponseWriter, r *http.Request) { + h.listVulnerabilitiesByFile(w, r, true) } //nolint:lll //swagger notations @@ -70,7 +71,7 @@ func (h *Handler) GetAllVulnerabilitiesByWorkspace(w http.ResponseWriter, r *htt // @Tags Vulnerabilities // @Security ApiKeyAuth // @Description Get all vulnerabilities data by repository -// @ID get-all-vulnerabilities-by-repository +// @ID list-vulnerabilities-by-file-repository // @Accept json // @Produce json // @Param workspaceID path string true "workspaceID of the workspace" @@ -78,24 +79,86 @@ func (h *Handler) GetAllVulnerabilitiesByWorkspace(w http.ResponseWriter, r *htt // @Param page query string false "page query string" // @Param size query string false "size query string" // @Param vulnHash query string false "vulnerability hash query string" -// @Param vulnType query string false "vulnerability type query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) -// @Param vulnSeverity query string false "vulnerability severity query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) -// @Success 200 {object} entities.Response{content=management.Response} "OK" +// @Param vulnType query string true "vulnerability type query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) +// @Param vulnSeverity query string false "vulnerability severity query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) +// @Param vulnFile query string true "vulnerability file query string" +// @Success 200 {object} entities.Response{content=management.ResponseVulnerabilitiesByFile} "OK" // @Failure 400 {object} entities.Response{content=string} "BAD REQUEST" // @Failure 500 {object} entities.Response{content=string} "INTERNAL SERVER ERROR" -// @Router /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID} [get] -func (h *Handler) GetAllVulnerabilitiesByRepository(w http.ResponseWriter, r *http.Request) { - h.getAllVulnerabilities(w, r) +// @Router /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files/vulnerabilities [get] +func (h *Handler) ListVulnerabilitiesByFileByRepository(w http.ResponseWriter, r *http.Request) { + h.listVulnerabilitiesByFile(w, r, true) } -func (h *Handler) getAllVulnerabilities(w http.ResponseWriter, r *http.Request) { - filter, err := h.useCases.ManagementFilterFromRequest(r) +func (h *Handler) listVulnerabilitiesByFile(w http.ResponseWriter, r *http.Request, validateVulnFile bool) { + filter, err := h.useCases.ManagementFilterFromRequest(r, validateVulnFile) if err != nil { httpUtil.StatusBadRequest(w, err) return } - result, err := h.controller.GetAllVulnerabilities(filter) + result, err := h.controller.ListVulnerabilitiesByFile(filter) + if err != nil { + httpUtil.StatusInternalServerError(w, err) + return + } + + httpUtil.StatusOK(w, result) +} + +//nolint:lll //swagger notations +// GetByWorkspace +// @Tags Vulnerabilities +// @Security ApiKeyAuth +// @Description Get all vulnerabilities data by repository +// @ID get-all-files-vulnerable-by-workspace +// @Accept json +// @Produce json +// @Param workspaceID path string true "workspaceID of the workspace" +// @Param page query string false "page query string" +// @Param size query string false "size query string" +// @Param vulnHash query string false "vulnerability hash query string" +// @Param vulnType query string true "vulnerability type query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) +// @Param vulnSeverity query string false "vulnerability severity query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) +// @Success 200 {object} entities.Response{content=management.ResponseFilesVulnerable} "OK" +// @Failure 400 {object} entities.Response{content=string} "BAD REQUEST" +// @Failure 500 {object} entities.Response{content=string} "INTERNAL SERVER ERROR" +// @Router /vulnerability/management/workspace/{workspaceID}/files [get] +func (h *Handler) ListVulnerableFilesByWorkspace(w http.ResponseWriter, r *http.Request) { + h.listVulnerableFiles(w, r, false) +} + +//nolint:lll //swagger notations +// GetByRepository +// @Tags Vulnerabilities +// @Security ApiKeyAuth +// @Description Get all vulnerabilities data by repository +// @ID get-all-files-vulnerable-by-repository +// @Accept json +// @Produce json +// @Param workspaceID path string true "workspaceID of the workspace" +// @Param repositoryID path string true "repositoryID of the repository" +// @Param page query string false "page query string" +// @Param size query string false "size query string" +// @Param vulnHash query string false "vulnerability hash query string" +// @Param vulnType query string true "vulnerability type query string" Enums(Vulnerability, Risk Accepted, False Positive, Corrected) +// @Param vulnSeverity query string false "vulnerability severity query string" Enums(CRITICAL, HIGH, MEDIUM, LOW, INFO) +// @Success 200 {object} entities.Response{content=management.ResponseFilesVulnerable} "OK" +// @Failure 400 {object} entities.Response{content=string} "BAD REQUEST" +// @Failure 500 {object} entities.Response{content=string} "INTERNAL SERVER ERROR" +// @Router /vulnerability/management/workspace/{workspaceID}/repository/{repositoryID}/files [get] +func (h *Handler) ListVulnerableFilesByRepository(w http.ResponseWriter, r *http.Request) { + h.listVulnerableFiles(w, r, false) +} + +func (h *Handler) listVulnerableFiles(w http.ResponseWriter, r *http.Request, validateVulnFile bool) { + filter, err := h.useCases.ManagementFilterFromRequest(r, validateVulnFile) + if err != nil { + httpUtil.StatusBadRequest(w, err) + return + } + + result, err := h.controller.ListVulnerableFiles(filter) if err != nil { httpUtil.StatusInternalServerError(w, err) return diff --git a/vulnerability/internal/handlers/management/management_test.go b/vulnerability/internal/handlers/management/management_test.go index 99a5eb35b..da29cdcc3 100644 --- a/vulnerability/internal/handlers/management/management_test.go +++ b/vulnerability/internal/handlers/management/management_test.go @@ -50,16 +50,16 @@ func TestOptions(t *testing.T) { }) } -func TestGetAllVulnerabilitiesByWorkspace(t *testing.T) { +func TestGetAllVulnerabilitiesOfTheFileByWorkspace(t *testing.T) { t.Run("should return 200 when success get vulnerabilities", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return(&managementEntities.Response{}, nil) + controllerMock.On("ListVulnerabilitiesByFile").Return(&managementEntities.ResponseVulnerabilitiesByFile{}, nil) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "god.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -71,7 +71,7 @@ func TestGetAllVulnerabilitiesByWorkspace(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) - handler.GetAllVulnerabilitiesByWorkspace(w, r) + handler.ListVulnerabilitiesByFileByWorkspace(w, r) assert.Equal(t, http.StatusOK, w.Code) }) @@ -79,13 +79,13 @@ func TestGetAllVulnerabilitiesByWorkspace(t *testing.T) { t.Run("should return 500 when something went wrong", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return( - &managementEntities.Response{}, errors.New("test")) + controllerMock.On("ListVulnerabilitiesByFile").Return( + &managementEntities.ResponseVulnerabilitiesByFile{}, errors.New("test")) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "god.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -97,7 +97,7 @@ func TestGetAllVulnerabilitiesByWorkspace(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) - handler.GetAllVulnerabilitiesByWorkspace(w, r) + handler.ListVulnerabilitiesByFileByWorkspace(w, r) assert.Equal(t, http.StatusInternalServerError, w.Code) }) @@ -105,30 +105,30 @@ func TestGetAllVulnerabilitiesByWorkspace(t *testing.T) { t.Run("should return 400 when invalid filter", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return( - &managementEntities.Response{}, errors.New("test")) + controllerMock.On("ListVulnerabilitiesByFile").Return( + &managementEntities.ResponseVulnerabilitiesByFile{}, errors.New("test")) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) r, _ := http.NewRequest(http.MethodGet, "/test", nil) w := httptest.NewRecorder() - handler.GetAllVulnerabilitiesByWorkspace(w, r) + handler.ListVulnerabilitiesByFileByWorkspace(w, r) assert.Equal(t, http.StatusBadRequest, w.Code) }) } -func TestGetAllVulnerabilitiesByRepository(t *testing.T) { +func TestGetAllVulnerabilitiesOfTheFileByRepository(t *testing.T) { t.Run("should return 200 when success get vulnerabilities", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return(&managementEntities.Response{}, nil) + controllerMock.On("ListVulnerabilitiesByFile").Return(&managementEntities.ResponseVulnerabilitiesByFile{}, nil) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -140,7 +140,7 @@ func TestGetAllVulnerabilitiesByRepository(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) - handler.GetAllVulnerabilitiesByRepository(w, r) + handler.ListVulnerabilitiesByFileByRepository(w, r) assert.Equal(t, http.StatusOK, w.Code) }) @@ -148,13 +148,13 @@ func TestGetAllVulnerabilitiesByRepository(t *testing.T) { t.Run("should return 500 when something went wrong", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return( - &managementEntities.Response{}, errors.New("test")) + controllerMock.On("ListVulnerabilitiesByFile").Return( + &managementEntities.ResponseVulnerabilitiesByFile{}, errors.New("test")) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", - severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456", "go.mod") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -166,7 +166,7 @@ func TestGetAllVulnerabilitiesByRepository(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) - handler.GetAllVulnerabilitiesByRepository(w, r) + handler.ListVulnerabilitiesByFileByRepository(w, r) assert.Equal(t, http.StatusInternalServerError, w.Code) }) @@ -174,15 +174,15 @@ func TestGetAllVulnerabilitiesByRepository(t *testing.T) { t.Run("should return 400 when invalid filter", func(t *testing.T) { controllerMock := &managementController.Mock{} - controllerMock.On("GetAllVulnerabilities").Return( - &managementEntities.Response{}, errors.New("test")) + controllerMock.On("ListVulnerabilitiesByFile").Return( + &managementEntities.ResponseVulnerabilitiesByFile{}, errors.New("test")) handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) r, _ := http.NewRequest(http.MethodGet, "/test", nil) w := httptest.NewRecorder() - handler.GetAllVulnerabilitiesByRepository(w, r) + handler.ListVulnerabilitiesByFileByRepository(w, r) assert.Equal(t, http.StatusBadRequest, w.Code) }) @@ -435,3 +435,141 @@ func TestUpdateVulnerabilitiesRepository(t *testing.T) { assert.Equal(t, http.StatusBadRequest, w.Code) }) } + +func TestGetAllFilesVulnerableByWorkspace(t *testing.T) { + t.Run("should return 200 when success get all files", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return(&managementEntities.ResponseFilesVulnerable{}, nil) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + + r, _ := http.NewRequest(http.MethodGet, URL, nil) + + w := httptest.NewRecorder() + + ctx := chi.NewRouteContext() + ctx.URLParams.Add("repositoryID", uuid.NewString()) + ctx.URLParams.Add("workspaceID", uuid.NewString()) + + r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) + + handler.ListVulnerableFilesByWorkspace(w, r) + + assert.Equal(t, http.StatusOK, w.Code) + }) + + t.Run("should return 500 when something went wrong", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return( + &managementEntities.ResponseFilesVulnerable{}, errors.New("test")) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + + r, _ := http.NewRequest(http.MethodGet, URL, nil) + + w := httptest.NewRecorder() + + ctx := chi.NewRouteContext() + ctx.URLParams.Add("repositoryID", uuid.NewString()) + ctx.URLParams.Add("workspaceID", uuid.NewString()) + + r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) + + handler.ListVulnerableFilesByWorkspace(w, r) + + assert.Equal(t, http.StatusInternalServerError, w.Code) + }) + + t.Run("should return 400 when invalid filter", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return( + &managementEntities.ResponseFilesVulnerable{}, errors.New("test")) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + r, _ := http.NewRequest(http.MethodGet, "/test", nil) + w := httptest.NewRecorder() + + handler.ListVulnerableFilesByWorkspace(w, r) + + assert.Equal(t, http.StatusBadRequest, w.Code) + }) +} + +func TestGetAllFilesVulnerableByRepository(t *testing.T) { + t.Run("should return 200 when success get vulnerabilities", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return(&managementEntities.ResponseFilesVulnerable{}, nil) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + + r, _ := http.NewRequest(http.MethodGet, URL, nil) + + w := httptest.NewRecorder() + + ctx := chi.NewRouteContext() + ctx.URLParams.Add("repositoryID", uuid.NewString()) + ctx.URLParams.Add("workspaceID", uuid.NewString()) + + r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) + + handler.ListVulnerableFilesByRepository(w, r) + + assert.Equal(t, http.StatusOK, w.Code) + }) + + t.Run("should return 500 when something went wrong", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return( + &managementEntities.ResponseFilesVulnerable{}, errors.New("test")) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") + + r, _ := http.NewRequest(http.MethodGet, URL, nil) + + w := httptest.NewRecorder() + + ctx := chi.NewRouteContext() + ctx.URLParams.Add("repositoryID", uuid.NewString()) + ctx.URLParams.Add("workspaceID", uuid.NewString()) + + r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) + + handler.ListVulnerableFilesByRepository(w, r) + + assert.Equal(t, http.StatusInternalServerError, w.Code) + }) + + t.Run("should return 400 when invalid filter", func(t *testing.T) { + controllerMock := &managementController.Mock{} + + controllerMock.On("ListVulnerableFiles").Return( + &managementEntities.ResponseFilesVulnerable{}, errors.New("test")) + + handler := NewManagementHandler(controllerMock, managementUseCases.NewManagementUseCases()) + + r, _ := http.NewRequest(http.MethodGet, "/test", nil) + w := httptest.NewRecorder() + + handler.ListVulnerableFilesByRepository(w, r) + + assert.Equal(t, http.StatusBadRequest, w.Code) + }) +} diff --git a/vulnerability/internal/repositories/management/management.go b/vulnerability/internal/repositories/management/management.go index def71efc3..82f1acc3e 100644 --- a/vulnerability/internal/repositories/management/management.go +++ b/vulnerability/internal/repositories/management/management.go @@ -29,7 +29,8 @@ import ( ) type IRepository interface { - GetAllVulnerabilities(filter *managementEntities.Filter) (*managementEntities.Response, error) + ListVulnerabilitiesByFile(filter *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) + ListVulnerableFiles(filter *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) GetVulnerability(vulnerabilityID uuid.UUID) (vuln *vulnerabilityEntities.Vulnerability, err error) GetAnalysis(analysisID uuid.UUID) (analysis *analysisEntities.Analysis, err error) } @@ -48,65 +49,130 @@ func NewManagementRepository(connection *database.Connection, useCases managemen } } -func (r *Repository) GetAllVulnerabilities(filter *managementEntities.Filter) (*managementEntities.Response, error) { - totalItems, err := r.getTotalVulnerabilities(filter) +func (r *Repository) ListVulnerableFiles( + filter *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) { + totalItems, err := r.getTotalFilesVulnerable(filter) if err != nil { return nil, err } - responseData, err := r.getVulnerabilitiesPaginated(filter) + responseData, err := r.getFilesVulnerablePaginated(filter) if err != nil { return nil, err } - return &managementEntities.Response{ + return &managementEntities.ResponseFilesVulnerable{ TotalItems: totalItems, Data: responseData, }, nil } -func (r *Repository) getTotalVulnerabilities(filter *managementEntities.Filter) (count int, err error) { - query, params := r.getTotalVulnerabilitiesQuery(filter) +func (r *Repository) ListVulnerabilitiesByFile( + filter *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) { + totalItems, err := r.getTotalVulnerabilitiesOfTheFile(filter) + if err != nil { + return nil, err + } + + responseData, err := r.getVulnerabilitiesOfTheFilePaginated(filter) + if err != nil { + return nil, err + } + + return &managementEntities.ResponseVulnerabilitiesByFile{ + TotalItems: totalItems, + Data: responseData, + }, nil +} + +func (r *Repository) getTotalFilesVulnerable(filter *managementEntities.Filter) (count int, err error) { + query, params := r.getTotalFilesVulnerableQuery(filter) + + return count, r.databaseRead.Raw(query, &count, params...).GetErrorExceptNotFound() +} + +func (r *Repository) getTotalVulnerabilitiesOfTheFile(filter *managementEntities.Filter) (count int, err error) { + query, params := r.getTotalVulnerabilitiesOfTheFileQuery(filter) return count, r.databaseRead.Raw(query, &count, params...).GetErrorExceptNotFound() } -func (r *Repository) getTotalVulnerabilitiesQuery(filter *managementEntities.Filter) (string, []interface{}) { +func (r *Repository) getTotalFilesVulnerableQuery(filter *managementEntities.Filter) (string, []interface{}) { condition, params := filter.GetWhereFilterQuery() return fmt.Sprintf(` - SELECT COUNT( DISTINCT ( vulnerabilities.vulnerability_id ) ) - FROM analysis + SELECT count(*) FROM ( + SELECT '-' as file FROM analysis + JOIN analysis_vulnerabilities ON analysis.analysis_id = analysis_vulnerabilities.analysis_id + JOIN vulnerabilities ON vulnerabilities.vulnerability_id = analysis_vulnerabilities.vulnerability_id + WHERE %[1]s + GROUP BY vulnerabilities.file + ) as count + `, condition), params +} + +func (r *Repository) getTotalVulnerabilitiesOfTheFileQuery(filter *managementEntities.Filter) (string, []interface{}) { + condition, params := filter.GetWhereFilterQuery() + + return fmt.Sprintf(` + SELECT COUNT( DISTINCT ( vulnerabilities.vulnerability_id ) ) FROM analysis JOIN analysis_vulnerabilities ON analysis.analysis_id = analysis_vulnerabilities.analysis_id JOIN vulnerabilities ON vulnerabilities.vulnerability_id = analysis_vulnerabilities.vulnerability_id WHERE %[1]s `, condition), params } -func (r *Repository) getVulnerabilitiesPaginated( - filter *managementEntities.Filter) (*[]managementEntities.ResponseData, error) { - responseData := &[]managementEntities.ResponseData{} +func (r *Repository) getFilesVulnerablePaginated( + filter *managementEntities.Filter) ([]managementEntities.ResponseDataFilesVulnerable, error) { + responseData := []managementEntities.ResponseDataFilesVulnerable{} + + query, params := r.getFilesVulnerablePaginatedQuery(filter) + + return responseData, r.databaseRead.Raw(query, &responseData, params...).GetErrorExceptNotFound() +} + +func (r *Repository) getVulnerabilitiesOfTheFilePaginated( + filter *managementEntities.Filter) ([]vulnerabilityEntities.Vulnerability, error) { + responseData := []vulnerabilityEntities.Vulnerability{} + + query, params := r.getVulnerabilitiesOfTheFilePaginatedQuery(filter) - query, params := r.getVulnerabilitiesPaginatedQuery(filter) + return responseData, r.databaseRead.Raw(query, &responseData, params...).GetErrorExceptNotFound() +} + +func (r *Repository) getFilesVulnerablePaginatedQuery( + filter *managementEntities.Filter) (string, []interface{}) { + condition, params := filter.GetWhereFilterQuery() - return responseData, r.databaseRead.Raw(query, responseData, params...).GetErrorExceptNotFound() + return fmt.Sprintf(` + SELECT * FROM ( + SELECT COUNT(vulnerabilities.vulnerability_id) as total_vulnerabilities, + vulnerabilities.file, analysis.created_at, analysis.analysis_id FROM analysis + JOIN analysis_vulnerabilities ON analysis.analysis_id = analysis_vulnerabilities.analysis_id + JOIN vulnerabilities ON vulnerabilities.vulnerability_id = analysis_vulnerabilities.vulnerability_id + WHERE %[1]s + GROUP BY vulnerabilities.file, analysis.created_at, analysis.analysis_id + ) AS tmpTable + ORDER BY tmpTable.total_vulnerabilities DESC, tmpTable.file + LIMIT @size OFFSET @skip + `, condition), params } -func (r *Repository) getVulnerabilitiesPaginatedQuery(filter *managementEntities.Filter) (string, []interface{}) { +func (r *Repository) getVulnerabilitiesOfTheFilePaginatedQuery( + filter *managementEntities.Filter) (string, []interface{}) { condition, params := filter.GetWhereFilterQuery() return fmt.Sprintf(` SELECT * FROM ( - SELECT vulnerabilities.*, analysis.analysis_id - FROM analysis + SELECT vulnerabilities.* FROM analysis JOIN analysis_vulnerabilities ON analysis.analysis_id = analysis_vulnerabilities.analysis_id JOIN vulnerabilities ON vulnerabilities.vulnerability_id = analysis_vulnerabilities.vulnerability_id WHERE %[1]s - GROUP BY vulnerabilities.vulnerability_id, analysis.analysis_id ) AS tmpTable ORDER BY CASE tmpTable.severity WHEN 'CRITICAL' THEN 1 WHEN 'HIGH' THEN 2 WHEN 'MEDIUM' THEN 3 WHEN 'LOW' THEN 4 - WHEN 'UNKNOWN' THEN 5 WHEN 'INFO' THEN 6 END, tmpTable.type DESC LIMIT @size OFFSET @skip + WHEN 'UNKNOWN' THEN 5 WHEN 'INFO' THEN 6 END + LIMIT @size OFFSET @skip `, condition), params } diff --git a/vulnerability/internal/repositories/management/management_mock.go b/vulnerability/internal/repositories/management/management_mock.go index 2cd0097cc..4386d6dc6 100644 --- a/vulnerability/internal/repositories/management/management_mock.go +++ b/vulnerability/internal/repositories/management/management_mock.go @@ -29,10 +29,16 @@ type Mock struct { mock.Mock } -func (m *Mock) GetAllVulnerabilities(_ *managementEntities.Filter) (*managementEntities.Response, error) { - args := m.MethodCalled("GetAllVulnerabilities") +func (m *Mock) ListVulnerabilitiesByFile(_ *managementEntities.Filter) (*managementEntities.ResponseVulnerabilitiesByFile, error) { + args := m.MethodCalled("ListVulnerabilitiesByFile") - return args.Get(0).(*managementEntities.Response), utilsMock.ReturnNilOrError(args, 1) + return args.Get(0).(*managementEntities.ResponseVulnerabilitiesByFile), utilsMock.ReturnNilOrError(args, 1) +} + +func (m *Mock) ListVulnerableFiles(_ *managementEntities.Filter) (*managementEntities.ResponseFilesVulnerable, error) { + args := m.MethodCalled("ListVulnerableFiles") + + return args.Get(0).(*managementEntities.ResponseFilesVulnerable), utilsMock.ReturnNilOrError(args, 1) } func (m *Mock) GetVulnerability(_ uuid.UUID) (vuln *vulnerabilityEntities.Vulnerability, err error) { diff --git a/vulnerability/internal/repositories/management/management_test.go b/vulnerability/internal/repositories/management/management_test.go index ce48680d0..60962adda 100644 --- a/vulnerability/internal/repositories/management/management_test.go +++ b/vulnerability/internal/repositories/management/management_test.go @@ -28,8 +28,8 @@ import ( managementUseCases "github.com/ZupIT/horusec-platform/vulnerability/internal/usecase/management" ) -func TestGetAllVulnerabilities(t *testing.T) { - t.Run("should success get vulnerability data", func(t *testing.T) { +func TestGetAllVulnerabilitiesOfTheFile(t *testing.T) { + t.Run("should success get all vulnerabilities of the file data", func(t *testing.T) { databaseMock := &database.Mock{} databaseMock.On("Raw").Return(&response.Response{}) @@ -40,7 +40,7 @@ func TestGetAllVulnerabilities(t *testing.T) { repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) - result, err := repository.GetAllVulnerabilities(&managementEntities.Filter{}) + result, err := repository.ListVulnerabilitiesByFile(&managementEntities.Filter{}) assert.NoError(t, err) assert.NotNil(t, result) }) @@ -58,7 +58,7 @@ func TestGetAllVulnerabilities(t *testing.T) { repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) - result, err := repository.GetAllVulnerabilities(&managementEntities.Filter{}) + result, err := repository.ListVulnerabilitiesByFile(&managementEntities.Filter{}) assert.Error(t, err) assert.Nil(t, result) }) @@ -75,7 +75,60 @@ func TestGetAllVulnerabilities(t *testing.T) { repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) - result, err := repository.GetAllVulnerabilities(&managementEntities.Filter{}) + result, err := repository.ListVulnerabilitiesByFile(&managementEntities.Filter{}) + assert.Error(t, err) + assert.Nil(t, result) + }) +} + +func TestGetAllFilesVulnerable(t *testing.T) { + t.Run("should success get all files vulnerable data", func(t *testing.T) { + databaseMock := &database.Mock{} + databaseMock.On("Raw").Return(&response.Response{}) + + databaseConnection := &database.Connection{ + Read: databaseMock, + Write: databaseMock, + } + + repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) + + result, err := repository.ListVulnerableFiles(&managementEntities.Filter{}) + assert.NoError(t, err) + assert.NotNil(t, result) + }) + + t.Run("should return error when getting vulns paginated", func(t *testing.T) { + databaseMock := &database.Mock{} + databaseMock.On("Raw").Once().Return(&response.Response{}) + databaseMock.On("Raw").Return( + response.NewResponse(0, errors.New("test"), nil)) + + databaseConnection := &database.Connection{ + Read: databaseMock, + Write: databaseMock, + } + + repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) + + result, err := repository.ListVulnerableFiles(&managementEntities.Filter{}) + assert.Error(t, err) + assert.Nil(t, result) + }) + + t.Run("should return error when getting total items", func(t *testing.T) { + databaseMock := &database.Mock{} + databaseMock.On("Raw").Once().Return( + response.NewResponse(0, errors.New("test"), nil)) + + databaseConnection := &database.Connection{ + Read: databaseMock, + Write: databaseMock, + } + + repository := NewManagementRepository(databaseConnection, managementUseCases.NewManagementUseCases()) + + result, err := repository.ListVulnerableFiles(&managementEntities.Filter{}) assert.Error(t, err) assert.Nil(t, result) }) diff --git a/vulnerability/internal/router/router.go b/vulnerability/internal/router/router.go index b1cba69c6..8adfaa935 100644 --- a/vulnerability/internal/router/router.go +++ b/vulnerability/internal/router/router.go @@ -70,10 +70,14 @@ func (r *Router) routerHealth() { func (r *Router) routerVulnerabilities() { r.Route(routes.ManagementVulnerabilitiesRouter, func(router chi.Router) { router.Options("/", r.managementHandler.Options) - router.With(r.IsRepositoryMember).Get("/workspace/{workspaceID}/repository/{repositoryID}", - r.managementHandler.GetAllVulnerabilitiesByRepository) - router.With(r.IsWorkspaceAdmin).Get("/workspace/{workspaceID}", - r.managementHandler.GetAllVulnerabilitiesByWorkspace) + router.With(r.IsRepositoryMember).Get("/workspace/{workspaceID}/repository/{repositoryID}/files", + r.managementHandler.ListVulnerableFilesByRepository) + router.With(r.IsRepositoryMember).Get("/workspace/{workspaceID}/files", + r.managementHandler.ListVulnerableFilesByWorkspace) + router.With(r.IsRepositoryMember).Get("/workspace/{workspaceID}/repository/{repositoryID}/files/vulnerabilities", + r.managementHandler.ListVulnerabilitiesByFileByRepository) + router.With(r.IsRepositoryMember).Get("/workspace/{workspaceID}/files/vulnerabilities", + r.managementHandler.ListVulnerabilitiesByFileByWorkspace) router.With(r.IsWorkspaceAdmin).Patch("/workspace/{workspaceID}/vulnerabilities", r.managementHandler.UpdateVulnerabilitiesByWorkspace) router.With(r.IsRepositorySupervisor).Patch("/workspace/{workspaceID}/repository/{repositoryID}/"+ diff --git a/vulnerability/internal/usecase/management/management.go b/vulnerability/internal/usecase/management/management.go index 60334c9de..917a09df0 100644 --- a/vulnerability/internal/usecase/management/management.go +++ b/vulnerability/internal/usecase/management/management.go @@ -27,7 +27,7 @@ import ( type IUseCases interface { UpdateDataFromIOReadCloser(body io.ReadCloser) (*managementEntities.UpdateData, error) - ManagementFilterFromRequest(request *http.Request) (*managementEntities.Filter, error) + ManagementFilterFromRequest(request *http.Request, validateVulnFile bool) (*managementEntities.Filter, error) FilterVulnerabilityByID(vulnerabilityID uuid.UUID) map[string]interface{} FilterAnalysisByID(analysisID uuid.UUID) map[string]interface{} } @@ -48,10 +48,14 @@ func (u *UseCases) UpdateDataFromIOReadCloser(body io.ReadCloser) (*managementEn return data, data.Validate() } -func (u *UseCases) ManagementFilterFromRequest(request *http.Request) (*managementEntities.Filter, error) { +func (u *UseCases) ManagementFilterFromRequest(request *http.Request, + validateVulnFile bool) (*managementEntities.Filter, error) { filter := &managementEntities.Filter{} - - return filter, filter.SetFilterDataFromRequest(request) + err := filter.SetFilterDataFromRequest(request, validateVulnFile) + if err != nil { + return nil, err + } + return filter, filter.Validate() } func (u *UseCases) FilterVulnerabilityByID(vulnerabilityID uuid.UUID) map[string]interface{} { diff --git a/vulnerability/internal/usecase/management/management_test.go b/vulnerability/internal/usecase/management/management_test.go index 85b25df1e..bff027d48 100644 --- a/vulnerability/internal/usecase/management/management_test.go +++ b/vulnerability/internal/usecase/management/management_test.go @@ -75,7 +75,7 @@ func TestManagementFilterFromRequest(t *testing.T) { id := uuid.New() - URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s", + URL := fmt.Sprintf("/test?page=1&size=15&vulnSeverity=%s&vulnType=%s&vulnHash=%s&vulnFile=go.mod", severities.Critical.ToString(), vulnerabilityEnums.Vulnerability.ToString(), "123456") r, _ := http.NewRequest(http.MethodGet, URL, nil) @@ -86,7 +86,7 @@ func TestManagementFilterFromRequest(t *testing.T) { r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx)) - filter, err := useCases.ManagementFilterFromRequest(r) + filter, err := useCases.ManagementFilterFromRequest(r, true) assert.NoError(t, err) assert.NotNil(t, filter) }) @@ -96,7 +96,7 @@ func TestManagementFilterFromRequest(t *testing.T) { r, _ := http.NewRequest(http.MethodGet, "/test", nil) - filter, err := useCases.ManagementFilterFromRequest(r) + filter, err := useCases.ManagementFilterFromRequest(r, true) assert.Error(t, err) assert.Empty(t, filter) })