diff --git a/docs/Configuration.md b/docs/Configuration.md index ea668f321..ebfeb11fb 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -182,7 +182,8 @@ gitlab: bitbucket: webhook-token: XXXXX token: XXXXX - url: https://api.bitbucket.org + url: https://bitbucket.org + api-url: https://api.bitbucket.org api-path: /2.0 false-positive-label: false-positive @@ -911,9 +912,10 @@ azure: ### Bitbucket (Cloud and Server) ```yaml bitbucket: - webhook-token + webhook-token: xxx token: :xxx - url: http://api.bitbucket.org + url: http://bitbucket.org + api-url: http://api.bitbucket.org api-path: /2.0 ``` @@ -921,7 +923,8 @@ bitbucket: |--------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `webhook-token` | | Token used as a shared secret when calling the CxFlow WebHook WebService. It authenticates users for the request. The Bitbucket cloud does not allow for a shared secret, therefore a URL parameter called token, must be provided in this case. | | `token` | | This is the API token with access to the repository with at least Read only access to code and the ability to add comments to pull requests. BitBucket requires the **:** format in the configuration.
`userid:app password`(Format while using BitBucket Cloud)
`userid:password`(Format while using BitBucket Server) | -| `url` | | - [https://api.bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://api.companyxyzbitbucket](https://api.companyxyzbitbucket) (URL for the BitBucket server is just the server hostname with `api.` prefixed) | +| `api-url` | | - [https://api.bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://api.companyxyzbitbucket](https://api.companyxyzbitbucket) (URL for the BitBucket server is just the server hostname with `api.` prefixed) | +| `url` | | - [https://bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://companyxyzbitbucket](https://api.companyxyzbitbucket)(URL for the BitBucket server is just the server hostname) | | `api-path` | | The API URL path (appended to the URL) for BitBucket | | 'scan-submitted-comment` | true | Comment on Merge Request with "Scan submitted (or not submitted) to Checkmarx ...". | diff --git a/src/main/java/com/checkmarx/flow/CxFlowRunner.java b/src/main/java/com/checkmarx/flow/CxFlowRunner.java index e7e452506..546ab446f 100644 --- a/src/main/java/com/checkmarx/flow/CxFlowRunner.java +++ b/src/main/java/com/checkmarx/flow/CxFlowRunner.java @@ -62,6 +62,7 @@ public class CxFlowRunner implements ApplicationRunner { private final FlowProperties flowProperties; private final CxScannerService cxScannerService; private final JiraProperties jiraProperties; + private final BitBucketProperties bitBucketProperties; private final GitHubProperties gitHubProperties; private final GitLabProperties gitLabProperties; private final IastService iastService; @@ -490,7 +491,20 @@ else if (args.containsOption("gitlab") && !ScanUtils.anyEmpty(namespace, repoNam gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP_OAUTH2.concat(token).concat("@")); scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.GITLAB, args); } else if (args.containsOption("bitbucket") && containsRepoArgs(namespace, repoName, branch)) { - log.warn("Bitbucket git clone scan not implemented"); + + repoUrl = getNonEmptyRepoUrl(namespace, repoName, repoUrl, bitBucketProperties.getGitUri(namespace, repoName)); + String token = bitBucketProperties.getToken(); + gitAuthUrl = repoUrl.replace(Constants.HTTPS, Constants.HTTPS.concat(token).concat("@")); + gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@")); + + scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.BITBUCKET, args); + } else if (args.containsOption("bitbucket-server") && containsRepoArgs(namespace, repoName, branch)) { + repoUrl = getNonEmptyRepoUrl(namespace, repoName, repoUrl, bitBucketProperties.getGitUri(namespace, repoName)); + String token = bitBucketProperties.getToken(); + gitAuthUrl = repoUrl.replace(Constants.HTTPS, Constants.HTTPS.concat(token).concat("@")); + gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@")); + + scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.BITBUCKETSERVER, args); } else if (args.containsOption("ado") && containsRepoArgs(namespace, repoName, branch)) { if (!args.containsOption(IAST_OPTION)) { if(adoProperties.getProjectName().isEmpty()){ @@ -503,6 +517,7 @@ else if (args.containsOption("gitlab") && !ScanUtils.anyEmpty(namespace, repoNam gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@")); scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.ADO, args); } + } } else if (file != null) { scanLocalPath(request, file); diff --git a/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java b/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java index d79ac1536..c601146df 100644 --- a/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java +++ b/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java @@ -28,4 +28,9 @@ public void setApiPath(String apiPath) { public void setIpAddresses(List ipAddresses) { this.ipAddresses = ipAddresses; } + + public String getGitUri(String namespace, String repoName) { + String format = "%s/%s/%s.git"; + return String.format(format, getUrl(), namespace, repoName); + } } diff --git a/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java b/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java index b1f13721b..1a43f539d 100644 --- a/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java +++ b/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java @@ -51,7 +51,7 @@ public class BatchComponentSteps { private final ThresholdValidator thresholdValidator; private final BuildProperties buildProperties; private final PDFProperties pdfProperties; - + private final BitBucketProperties bitBucketProperties; private CxFlowRunner cxFlowRunner; private String projectName; private String teamName; @@ -71,6 +71,7 @@ public void sastClientIsMocked() throws CheckmarxException { cxFlowRunner = new CxFlowRunner(flowProperties, cxScannerService, jiraProperties, + bitBucketProperties, gitHubProperties, gitLabProperties, iastService, diff --git a/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java b/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java index 86057bd39..0f07126c3 100644 --- a/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java +++ b/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java @@ -105,6 +105,7 @@ public class IastCliSteps { private final List scanners; private final ThresholdValidator thresholdValidator; private final PDFProperties pdfProperties; + private final BitBucketProperties bitBucketProperties; private String urlRequest; private HttpHeaders headers; @@ -120,6 +121,7 @@ public void mockCliRunner(String scanTag, String bugTracker, String params) { flowProperties, cxScannerService, jiraProperties, + bitBucketProperties, gitHubProperties, gitLabProperties, iastService,