Skip to content

Commit

Permalink
Add bitbucket support to finding view SCM urls (#9262)
Browse files Browse the repository at this point in the history
* add bitbucket support for Finging view scm urls, some tests for it and appropriate doc update

:bug: fix typo for MSDefender in settings.dist.py (#9249)

Bump boto3 from 1.34.9 to 1.34.11 (#9254)

Bumps [boto3](https://github.com/boto/boto3) from 1.34.9 to 1.34.11.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](boto/boto3@1.34.9...1.34.11)

---
updated-dependencies:
- dependency-name: boto3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Update versions in application files

Update release-x-manual-helm-chart.yml

Update release-x-manual-helm-chart.yml

Update versions in application files

Bump lxml from 4.9.4 to 5.0.0 (#9251)

Bumps [lxml](https://github.com/lxml/lxml) from 4.9.4 to 5.0.0.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](lxml/lxml@lxml-4.9.4...lxml-5.0.0)

---
updated-dependencies:
- dependency-name: lxml
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Update rabbitmq:3.12.11-alpine Docker digest from 3.12.11 to 3.12.11-alpine (docker-compose.yml) (#9240)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

Bump sqlalchemy from 2.0.23 to 2.0.24 (#9244)

Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.23 to 2.0.24.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump drf-spectacular-sidecar from 2023.12.1 to 2024.1.1 (#9252)

Bumps [drf-spectacular-sidecar](https://github.com/tfranzel/drf-spectacular-sidecar) from 2023.12.1 to 2024.1.1.
- [Commits](tfranzel/drf-spectacular-sidecar@2023.12.1...2024.1.1)

---
updated-dependencies:
- dependency-name: drf-spectacular-sidecar
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Update manusa/actions-setup-minikube action from v2.9.0 to v2.10.0 (.github/workflows/k8s-tests.yml) (#9257)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

fix pep8

fix imports

Bump sqlalchemy from 2.0.24 to 2.0.25 (#9266)

Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.24 to 2.0.25.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump pillow from 10.1.0 to 10.2.0 (#9265)

Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](python-pillow/Pillow@10.1.0...10.2.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

:bug: fix zap, issue #9242 (#9243)

* 🐛 fix zap, issue #9242

* adapt identiation

API: Add Announcements (#9112)

* Add Announcement to API

* Add test_rest_framework

* Add test_swagger_schema

* Flake8

* Fix count

* Skip test

* Inc db_mig

* Use DojoModelViewSet

* inc db_mig

:bug: None Type in cvss score in Trivy #9263e (#9268)

Feature: Add Auditlog Retention and Cleanup (#9208)

* feat: add auditlog retention

* linting: satisfy flake8

* fix: forgot imports in tasks.py

* fix: add necessary test-data

* Update unittests/test_flush_auditlog.py

Co-authored-by: kiblik <kiblik@gjh.sk>

* Update unittests/test_flush_auditlog.py

Co-authored-by: kiblik <kiblik@gjh.sk>

* Update unittests/test_flush_auditlog.py

Co-authored-by: kiblik <kiblik@gjh.sk>

* Update dojo/tasks.py

Co-authored-by: kiblik <kiblik@gjh.sk>

* Update unittests/test_flush_auditlog.py

Co-authored-by: kiblik <kiblik@gjh.sk>

* Update test_flush_auditlog.py

removed spaces

* fix: change default value for the retetion period to disable log recycling and mimic the default behavior. Then no change will happen until a user actively sets/ changes this parameter

---------

Co-authored-by: MarianG <marian.gawron@deutschebahn.com>
Co-authored-by: kiblik <kiblik@gjh.sk>

fix doc

* Update docs/content/en/integrations/source-code-repositories.md

Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com>

* Update docs/content/en/integrations/source-code-repositories.md

Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com>

* Update dojo/models.py

Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com>

* Update dojo/models.py

Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com>

---------

Co-authored-by: DVSutyagin <dvsutyagin@greenatom.ru>
Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 10, 2024
1 parent 9924957 commit b2be9d4
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 17 deletions.
39 changes: 34 additions & 5 deletions docs/content/en/integrations/source-code-repositories.md
Expand Up @@ -7,18 +7,47 @@ weight: 5

Findings can have a filepath and a line number as the location of the vulnerability. This is typically set when scanning an application with a Static Application Security Test (SAST) tool. If the repository of the source code is specified in the Engagement, DefectDojo will present the filepath as a link and the user can navigate directly to the location of the vulnerability.

## Setting the repository in the Engagement
## Setting the repository in the Engagement and Test

While editing the Engagement, users can set the URL of the repo. It needs to be the URL including the branch, e.g. https://github.com/DefectDojo/django-DefectDojo/tree/dev (GitHub) or https://gitlab.com/gitlab-org/gitlab/-/tree/master (GitLab).
### Engagement
While editing the Engagement, users can set the URL of the specific SCM repo.
For Interactive Engagement it needs to be the URL including the branch:
- for GitHub - like https://github.com/DefectDojo/django-DefectDojo/tree/dev
![Edit Engagement (GitHub)](../../../static/images/source-code-repositories_1.png)
- for GitLab - like https://gitlab.com/gitlab-org/gitlab/-/tree/master
![Edit Engagement (Gitlab)](../../../static/images/source-code-repositories-gitlab_1.png)
- for public BitBucket - like (like git clone url)
![Edit Engagement (Bitbucket public)](../../../static/images/source-code-repositories-bitbucket_1.png)
- for standalone/onpremise BitBucket https://bb.example.com/scm/some-project/some-repo.git or https://bb.example.com/scm/some-user-name/some-repo.git for user public repo (like git clone url)
![Edit Engagement (Bitbucket standalone)](../../../static/images/source-code-repositories-bitbucket-onpremise_1.png)

For CI/CD Engagement, where user could set commit hash, branch/tag and code line it should look like examples below:
- for GitHub - like https://github.com/DefectDojo/django-DefectDojo
- for GitLab - like https://gitlab.com/gitlab-org/gitlab
- for public BitBucket - like https://bitbucket.org/some-user/some-project.git (like git clone url)
- for standalone/onpremise BitBucket https://bb.example.com/scm/some-project.git or https://bb.example.com/scm/some-user-name/some-repo.git for user public repo (like git clone url)

If user does not set commit hash or branch/tag in appropriate fields of CI/CD Engagement edit form, the URL should look like in Interactive Engagement edit form.

SCM navigation URL is composed from Repo URL using SCM Type. Github/Gitlab SCM type is default, but user could set certain SCM type in Product custom field "scm-type".

Product custom fields:

![Product custom fields](../../../static/images/product-custom-fields_1.png)

Product SCM type add:

![Product scm type](../../../static/images/product-scm-type_1.png)

Possible SCM types could be 'github', 'gitlab', 'bitbucket', 'bitbucket-standalone' or nothing (for default github).

![Edit Engagement](../../images/source-code-repositories_1.png)

## Link in Finding

When viewing a finding, the location will be presented as a link, if the repository of the source code has been set in the Engagement:

![Link to location](../../images/source-code-repositories_2.png)
![Link to location](../../../static/images/source-code-repositories_2.png)

Clicking on this link will open a new tab in the browser, with the source file of the vulnerability at the corresponding line number:

![View in repository](../../images/source-code-repositories_3.png)
![View in repository](../../../static/images/source-code-repositories_3.png)
Binary file added docs/static/images/product-custom-fields_1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/images/product-scm-type_1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 110 additions & 11 deletions dojo/models.py
Expand Up @@ -3027,26 +3027,125 @@ def get_file_path_with_link(self):
link = self.get_file_path_with_raw_link()
return create_bleached_link(link, self.file_path)

def get_scm_type(self):
# extract scm type from product custom field 'scm-type'

if hasattr(self.test.engagement, 'product'):
dojo_meta = DojoMeta.objects.filter(product=self.test.engagement.product, name='scm-type').first()
if dojo_meta:
st = dojo_meta.value.strip()
if st:
return st.lower()
return 'github'

def bitbucket_public_prepare_scm_base_link(self, uri):
# bitbucket public (https://bitbucket.org) url template for browse is:
# https://bitbucket.org/<username>/<repository-slug>
# but when you get repo url for git, its template is:
# https://bitbucket.org/<username>/<repository-slug>.git
# so to create browser url - git url should be recomposed like below:

parts_uri = uri.split('.git')
return parts_uri[0]

def bitbucket_public_prepare_scm_link(self, uri):
# if commit hash or branch/tag is set for engagement/test -
# hash or branch/tag should be appended to base browser link

link = self.bitbucket_public_prepare_scm_base_link(uri)
if self.test.commit_hash:
link += '/src/' + self.test.commit_hash + '/' + self.file_path
elif self.test.engagement.commit_hash:
link += '/src/' + self.test.engagement.commit_hash + '/' + self.file_path
elif self.test.branch_tag:
link += '/src/' + self.test.branch_tag + '/' + self.file_path
elif self.test.engagement.branch_tag:
link += '/src/' + self.test.engagement.branch_tag + '/' + self.file_path
else:
link += '/src/master/' + self.file_path

return link

def bitbucket_standalone_prepare_scm_base_link(self, uri):
# bitbucket onpremise/standalone url template for browse is:
# https://bb.example.com/projects/<project-key>/repos/<repository-slug>
# but when you get repo url for git, its template is:
# https://bb.example.com/scm/<project-key>/<repository-slug>.git
# or for user public repo^
# https://bb.example.com/users/<username>/repos/<repository-slug>
# but when you get repo url for git, its template is:
# https://bb.example.com/scm/<username>/<repository-slug>.git (username often could be prefixed with ~)
# so to create borwser url - git url should be recomposed like below:

parts_uri = uri.split('.git')
parts_scm = parts_uri[0].split('/scm/')
parts_project = parts_scm[1].split('/')
project = parts_project[0]
if project.startswith('~'):
return parts_scm[0] + '/users/' + parts_project[0][1:] + '/repos/' + parts_project[1] + '/browse'
else:
return parts_scm[0] + '/projects/' + parts_project[0] + '/repos/' + parts_project[1] + '/browse'

def bitbucket_standalone_prepare_scm_link(self, uri):
# if commit hash or branch/tag is set for engagement/test -
# hash or barnch/tag should be appended to base browser link

link = self.bitbucket_standalone_prepare_scm_base_link(uri)
if self.test.commit_hash:
link += '/' + self.file_path + '?at=' + self.test.commit_hash
elif self.test.engagement.commit_hash:
link += '/' + self.file_path + '?at=' + self.test.engagement.commit_hash
elif self.test.branch_tag:
link += '/' + self.file_path + '?at=' + self.test.branch_tag
elif self.test.engagement.branch_tag:
link += '/' + self.file_path + '?at=' + self.test.engagement.branch_tag
else:
link += '/' + self.file_path

return link

def github_prepare_scm_link(self, uri):
link = uri

if self.test.commit_hash:
link += '/blob/' + self.test.commit_hash + '/' + self.file_path
elif self.test.engagement.commit_hash:
link += '/blob/' + self.test.engagement.commit_hash + '/' + self.file_path
elif self.test.branch_tag:
link += '/blob/' + self.test.branch_tag + '/' + self.file_path
elif self.test.engagement.branch_tag:
link += '/blob/' + self.test.engagement.branch_tag + '/' + self.file_path
else:
link += '/' + self.file_path

return link

def get_file_path_with_raw_link(self):
if self.file_path is None:
return None

link = self.test.engagement.source_code_management_uri
if (self.test.engagement.source_code_management_uri is not None
and "https://github.com/" in self.test.engagement.source_code_management_uri):
if self.test.commit_hash:
link += '/blob/' + self.test.commit_hash + '/' + self.file_path
elif self.test.engagement.commit_hash:
link += '/blob/' + self.test.engagement.commit_hash + '/' + self.file_path
elif self.test.branch_tag:
link += '/blob/' + self.test.branch_tag + '/' + self.file_path
elif self.test.engagement.branch_tag:
link += '/blob/' + self.test.engagement.branch_tag + '/' + self.file_path
scm_type = self.get_scm_type()
if (self.test.engagement.source_code_management_uri is not None):
if scm_type == 'github' or ("https://github.com/" in self.test.engagement.source_code_management_uri):
link = self.github_prepare_scm_link(link)
elif scm_type == 'bitbucket-standalone':
link = self.bitbucket_standalone_prepare_scm_link(link)
elif scm_type == 'bitbucket':
link = self.bitbucket_public_prepare_scm_link(link)
else:
link += '/' + self.file_path
else:
link += '/' + self.file_path

# than - add line part to browser url
if self.line:
link = link + '#L' + str(self.line)
if scm_type == 'github' or scm_type == 'gitlab':
link = link + '#L' + str(self.line)
elif scm_type == 'bitbucket-standalone':
link = link + '#' + str(self.line)
elif scm_type == 'bitbucket':
link = link + '#lines-' + str(self.line)
return link

def get_references_with_links(self):
Expand Down
161 changes: 160 additions & 1 deletion unittests/test_finding_model.py
@@ -1,5 +1,5 @@
from .dojo_test_case import DojoTestCase
from dojo.models import Finding, Test, Engagement
from dojo.models import Finding, Test, Engagement, DojoMeta


class TestFindingModel(DojoTestCase):
Expand Down Expand Up @@ -50,6 +50,165 @@ def test_get_file_path_with_link_and_source_code_management_uri(self):
engagement.source_code_management_uri = 'URL'
self.assertEqual('<a href=\"URL/FilePath\" target=\"_blank\" title=\"FilePath\">FilePath</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_github_no_scm_type_with_details_and_line(self):
# checks that for github.com in uri dojo makes correct url to browse on github

test = Test()
engagement = Engagement()
test.engagement = engagement
engagement.commit_hash = "some-commit-hash"
engagement.branch_tag = "some-branch"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432
engagement.source_code_management_uri = 'https://github.com/some-test-account/some-test-repo'
self.assertEqual('<a href=\"https://github.com/some-test-account/some-test-repo/blob/some-commit-hash/some-folder/some-file.ext#L5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_github_with_scm_type_with_details_and_line(self):
# checks that for github in custom field dojo makes correct url to browse on github

# create scm-type custom field with value "github"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="github")
product_metadata.save()

# create finding with scm uri and commit hash, branch and line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
engagement.commit_hash = "some-commit-hash"
engagement.branch_tag = "some-branch"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://github.com/some-test-account/some-test-repo'
self.assertEqual('<a href=\"https://github.com/some-test-account/some-test-repo/blob/some-commit-hash/some-folder/some-file.ext#L5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_bitbucket_public_project_with_no_details_and_line(self):
# checks that for public bitbucket (bitbucket.org) in custom field
# dojo makes correct url to browse on public bitbucket (for project uri)

# create scm-type custom field with value "bitbucket"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="bitbucket")
product_metadata.save()

# create finding with scm uri line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://bb.example.com/some-test-user/some-test-repo.git'
self.assertEqual('<a href=\"https://bb.example.com/some-test-user/some-test-repo/src/master/some-folder/some-file.ext#lines-5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_bitbucket_public_project_with_commithash_and_line(self):
# checks that for public bitbucket (bitbucket.org) in custom field and existing commit hash in finding
# dojo makes correct url to browse on public bitbucket (for project uri)

# create scm-type custom field with value "bitbucket"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="bitbucket")
product_metadata.save()

# create finding with scm uri and commit hash, branch and line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
engagement.commit_hash = "some-commit-hash"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://bb.example.com/some-test-user/some-test-repo.git'
self.assertEqual('<a href=\"https://bb.example.com/some-test-user/some-test-repo/src/some-commit-hash/some-folder/some-file.ext#lines-5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_bitbucket_standalone_project_with_commithash_and_line(self):
# checks that for standalone bitbucket in custom field and existing commit hash in finding
# dojo makes correct url to browse on standalone/onpremise bitbucket (for project uri)

# create scm-type custom field with value "bitbucket-standalone"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="bitbucket-standalone")
product_metadata.save()

# create finding with scm uri and commit hash, branch and line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
engagement.commit_hash = "some-commit-hash"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://bb.example.com/scm/some-test-project/some-test-repo.git'
self.assertEqual('<a href=\"https://bb.example.com/projects/some-test-project/repos/some-test-repo/browse/some-folder/some-file.ext?at=some-commit-hash#5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_bitbucket_standalone_project_with_branchtag_and_line(self):
# checks that for standalone bitbucket in custom field and existing branch/tag in finding
# dojo makes correct url to browse on standalone/onpremise bitbucket (for project uri)

# create scm-type custom field with value "bitbucket-standalone"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="bitbucket-standalone")
product_metadata.save()

# create finding with scm uri and commit hash, branch and line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
engagement.branch_tag = "some-branch"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://bb.example.com/scm/some-test-project/some-test-repo.git'
self.assertEqual('<a href=\"https://bb.example.com/projects/some-test-project/repos/some-test-repo/browse/some-folder/some-file.ext?at=some-branch#5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_link_and_source_code_management_uri_bitbucket_standalone_user_with_branchtag_and_line(self):
# checks that for standalone bitbucket in custom field and existing branch/tag in finding
# dojo makes correct url to browse on standalone/onpremise bitbucket (for user uri)

# create scm-type custom field with value "bitbucket-standalone"
product_type = self.create_product_type('test_product_type')
product = self.create_product(name='test_product', prod_type=product_type)
product_metadata = DojoMeta(product=product, name="scm-type", value="bitbucket-standalone")
product_metadata.save()

# create finding with scm uri and commit hash, branch and line
test = Test()
engagement = Engagement()
engagement.product = product
test.engagement = engagement
engagement.branch_tag = "some-branch"
finding = Finding()
finding.test = test
finding.file_path = 'some-folder/some-file.ext'
finding.line = 5432

engagement.source_code_management_uri = 'https://bb.example.com/scm/~some-user/some-test-repo.git'

self.assertEqual('<a href=\"https://bb.example.com/users/some-user/repos/some-test-repo/browse/some-folder/some-file.ext?at=some-branch#5432" target=\"_blank\" title=\"some-folder/some-file.ext\">some-folder/some-file.ext</a>', finding.get_file_path_with_link())

def test_get_file_path_with_xss_attack(self):
test = Test()
engagement = Engagement()
Expand Down

0 comments on commit b2be9d4

Please sign in to comment.