diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 809be5e..1e8128e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -25,6 +25,3 @@ RUN cd /opt && \ # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends - - - diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7f20c43..2ee6de7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -56,4 +56,4 @@ }, // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode" -} \ No newline at end of file +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 9e0a600..af9261f 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -14,7 +14,7 @@ services: NODE_VERSION: "lts/*" volumes: - - ..:/workspace:cached + - ..:/workspace:cached init: true # Overrides default command so things don't shut down after the process ends. diff --git a/.github/workflows/azure-container-webapp.yml b/.github/workflows/azure-container-webapp.yml index 50cc79c..b26060e 100644 --- a/.github/workflows/azure-container-webapp.yml +++ b/.github/workflows/azure-container-webapp.yml @@ -35,7 +35,7 @@ env: on: push: - branches: [ "main" ] + branches: [ main ] pull_request: workflow_dispatch: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46a9742..3ac3c5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,21 @@ name: CI on: push: - branches: main + branches: [ main ] pull_request: workflow_dispatch: jobs: + pre-commit-check: + runs-on: ubuntu-latest + name: "Run the pre-commit hooks" + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.9 + - uses: pre-commit/action@v3.0.0 + test: runs-on: ubuntu-latest name: test (Python ${{ matrix.python-version }}) diff --git a/.idea/misc.xml b/.idea/misc.xml index f0621b3..4ac1eb8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/.idea/modules.xml b/.idea/modules.xml index 4850baf..2389d5c 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -5,4 +5,4 @@ - \ No newline at end of file + diff --git a/.idea/omega-triage-portal.iml b/.idea/omega-triage-portal.iml index 49b0e52..af7c37e 100644 --- a/.idea/omega-triage-portal.iml +++ b/.idea/omega-triage-portal.iml @@ -5,6 +5,7 @@ + @@ -17,4 +18,4 @@ - \ No newline at end of file + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..dcb6b8c 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5ab8ef1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +exclude: '.idea' +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: debug-statements + - id: name-tests-test + - id: requirements-txt-fixer + - repo: https://github.com/asottile/add-trailing-comma + rev: v2.4.0 + hooks: + - id: add-trailing-comma + args: [--py36-plus] + - repo: https://github.com/asottile/pyupgrade + rev: v3.3.1 + hooks: + - id: pyupgrade + args: [--py38-plus] + - repo: https://github.com/iamthefij/docker-pre-commit + rev: v3.0.1 + hooks: + - id: docker-compose-check + - repo: https://github.com/pryorda/dockerfilelint-precommit-hooks + rev: v0.1.0 + hooks: + - id: dockerfilelint + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.22.0 + hooks: + - id: check-github-workflows + - id: check-dependabot diff --git a/.vscode/launch.json b/.vscode/launch.json index bfb0291..40f0bd4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,4 +16,4 @@ "django": true } ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f2a1b8..0e20c75 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -39,4 +39,4 @@ }, "editor.bracketPairColorization.enabled": true, "html.format.templating": true -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5ee406b..34eaf69 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -90,4 +90,4 @@ }, }, ] -} \ No newline at end of file +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..750fe64 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing + +## Getting Started + +Please read the [README](./README.md) for more information about the project. + +## Pre-Commit Hooks + +### Installing + +This project uses `pre-commit` to run a series of checks before each commit. +If you don't already have `pre-commit` installed, you can install globally with: + +```bash +pip install pre-commit +``` +Alternatively, you can use homebrew on macOS: + +```bash +brew install pre-commit +``` + +Then, to install the pre-commit hooks, run: + +```bash +pre-commit install +``` + +### Executing + +The pre-commit hooks will run automatically before each commit. +However, many of the hooks can be used to automatically fix issues as well. +To run the pre-commit hooks manually and resolve easily fixed issues, run: + +```bash +pre-commit run --all-files +``` diff --git a/README.md b/README.md index 065a557..2bc791b 100644 --- a/README.md +++ b/README.md @@ -61,4 +61,3 @@ TBD ## Security See [SECURITY.md](https://github.com/ossf/omega-triage-portal/blob/main/SECURITY.md). - diff --git a/docker-entrypoint-initdb.d b/docker-entrypoint-initdb.d index 2f714d2..0d673f6 100644 --- a/docker-entrypoint-initdb.d +++ b/docker-entrypoint-initdb.d @@ -5,4 +5,4 @@ psql -v ON_ERROR_STOP=1 --username "$DATABASE_USER" --dbname "$DATABASE_NAME" << CREATE USER triage_user; CREATE DATABASE triage; GRANT ALL PRIVILEGES ON DATABASE triage_user TO triage_user; -EOSQL \ No newline at end of file +EOSQL diff --git a/src/.env-template b/src/.env-template index dcb00d7..8e94c35 100644 --- a/src/.env-template +++ b/src/.env-template @@ -21,4 +21,4 @@ CACHE_REDIS_PASSWORD='' #APPINSIGHTS_IKEY = '' -OSSGADGET_PATH="/opt/OSSGadget" \ No newline at end of file +OSSGADGET_PATH="/opt/OSSGadget" diff --git a/src/Dockerfile b/src/Dockerfile index b953328..3d721e0 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -23,7 +23,7 @@ RUN cd /opt && \ mv OSSGadget_linux_${OSSGADGET_VERSION} OSSGadget -RUN apk update && apk add gcc \ +RUN apk update && apk add --no-cache gcc \ libc-dev \ postgresql-dev \ musl-dev \ diff --git a/src/core/__init__.py b/src/core/__init__.py index 64952bf..2bc27a5 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -17,7 +17,7 @@ def get_env_variable(var_name, optional=False): if optional: return False raise ImproperlyConfigured( - f"Error: You must set the {var_name} environment variable." + f"Error: You must set the {var_name} environment variable.", ) from ex diff --git a/src/core/settings.py b/src/core/settings.py index 5d65c22..826df41 100644 --- a/src/core/settings.py +++ b/src/core/settings.py @@ -15,7 +15,7 @@ dotenv.load_dotenv(os.path.join(BASE_DIR, ".env-template")) except Exception as ex: raise ImproperlyConfigured( - "A .env-template file was not found. Environment variables are not set." + "A .env-template file was not found. Environment variables are not set.", ) from ex SECRET_KEY = os.getenv("SECRET_KEY") @@ -92,7 +92,7 @@ "HOST": os.getenv("DATABASE_HOST"), "PORT": os.getenv("DATABASE_PORT"), "OPTIONS": {"options": "-c statement_timeout=5000"}, - } + }, } @@ -146,7 +146,7 @@ "TIMEOUT": DEFAULT_CACHE_TIMEOUT, "PASSWORD": os.getenv("CACHE_REDIS_PASSWORD"), }, - } + }, } else: CACHES = { @@ -237,5 +237,5 @@ "default": { "provider": "triage.util.content_managers.file_manager.FileManager", "args": {"root_path": "/home/vscode/omega-fs"}, - } + }, } diff --git a/src/manage.py b/src/manage.py index bb023c8..274c14e 100755 --- a/src/manage.py +++ b/src/manage.py @@ -14,7 +14,7 @@ def main(): raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" + "forget to activate a virtual environment?", ) from exc execute_from_command_line(sys.argv) diff --git a/src/pyproject.toml b/src/pyproject.toml index 300bd1e..7a054dc 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -545,5 +545,3 @@ ignored-argument-names = "_.*|^ignored_|^unused_" # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules = ["six.moves", "past.builtins", "future.builtins", "builtins", "io"] - - diff --git a/src/requirements.txt b/src/requirements.txt index 0ba77d5..07cc387 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -4,13 +4,13 @@ azure-core==1.26.1 azure-storage-blob==12.14.1 bandit==1.7.5 black==22.10.0 -cryptography==39.0.1 +celery==5.2.7 certifi==2022.12.7 cffi==1.15.1 -celery==5.2.7 charset-normalizer<3,>=2 click==8.1.3 cryptography==39.0.1 +cryptography==39.0.1 data==0.4 Deprecated==1.2.13 dill==0.3.6 @@ -53,8 +53,8 @@ pylint-django==2.5.3 pylint-flask==0.6 pylint-plugin-utils==0.7 pyparsing==3.0.9 -python-magic==0.4.27 python-dotenv==1.0.0 +python-magic==0.4.27 pytz==2022.6 PyYAML==6.0 redis==4.5.4 diff --git a/src/triage/apps.py b/src/triage/apps.py index d7fce05..3f8ea8f 100644 --- a/src/triage/apps.py +++ b/src/triage/apps.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """This module configures application-level settings for the Triage Portal.""" import logging diff --git a/src/triage/migrations/0001_initial.py b/src/triage/migrations/0001_initial.py index 5d92000..172b220 100644 --- a/src/triage/migrations/0001_initial.py +++ b/src/triage/migrations/0001_initial.py @@ -37,7 +37,10 @@ class Migration(migrations.Migration): ( "package_url", models.CharField( - blank=True, db_index=True, max_length=1024, null=True + blank=True, + db_index=True, + max_length=1024, + null=True, ), ), ("metadata", models.JSONField(null=True)), @@ -83,7 +86,10 @@ class Migration(migrations.Migration): ( "package_url", models.CharField( - blank=True, db_index=True, max_length=1024, null=True + blank=True, + db_index=True, + max_length=1024, + null=True, ), ), ("metadata", models.JSONField(null=True)), @@ -98,7 +104,8 @@ class Migration(migrations.Migration): ( "project", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="triage.project" + on_delete=django.db.models.deletion.CASCADE, + to="triage.project", ), ), ( @@ -144,7 +151,9 @@ class Migration(migrations.Migration): ( "type", models.CharField( - choices=[("PY", "Python Function")], default="PY", max_length=2 + choices=[("PY", "Python Function")], + default="PY", + max_length=2, ), ), ], @@ -246,7 +255,8 @@ class Migration(migrations.Migration): ( "tool", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="triage.tool" + on_delete=django.db.models.deletion.CASCADE, + to="triage.tool", ), ), ( @@ -413,7 +423,8 @@ class Migration(migrations.Migration): ( "scan", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="triage.scan" + on_delete=django.db.models.deletion.CASCADE, + to="triage.scan", ), ), ( diff --git a/src/triage/migrations/0003_auto_20211127_0020.py b/src/triage/migrations/0003_auto_20211127_0020.py index c427501..1cca0f8 100644 --- a/src/triage/migrations/0003_auto_20211127_0020.py +++ b/src/triage/migrations/0003_auto_20211127_0020.py @@ -65,7 +65,8 @@ class Migration(migrations.Migration): ( "tool", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="triage.tool" + on_delete=django.db.models.deletion.CASCADE, + to="triage.tool", ), ), ], diff --git a/src/triage/migrations/0012_filecontent_remove_finding_file_path_file_and_more.py b/src/triage/migrations/0012_filecontent_remove_finding_file_path_file_and_more.py index de796de..d20966b 100644 --- a/src/triage/migrations/0012_filecontent_remove_finding_file_path_file_and_more.py +++ b/src/triage/migrations/0012_filecontent_remove_finding_file_path_file_and_more.py @@ -28,7 +28,10 @@ class Migration(migrations.Migration): ( "content_type", models.CharField( - blank=True, db_index=True, max_length=64, null=True + blank=True, + db_index=True, + max_length=64, + null=True, ), ), ("data", models.BinaryField(blank=True, null=True)), diff --git a/src/triage/migrations/0015_alter_finding_analyst_severity_level_and_more.py b/src/triage/migrations/0015_alter_finding_analyst_severity_level_and_more.py index e5e6ae8..dac4be8 100644 --- a/src/triage/migrations/0015_alter_finding_analyst_severity_level_and_more.py +++ b/src/triage/migrations/0015_alter_finding_analyst_severity_level_and_more.py @@ -32,7 +32,10 @@ class Migration(migrations.Migration): model_name="finding", name="normalized_title", field=models.CharField( - blank=True, db_index=True, max_length=1024, null=True + blank=True, + db_index=True, + max_length=1024, + null=True, ), ), migrations.AlterField( diff --git a/src/triage/migrations/0017_tooldefect_created_at_tooldefect_created_by_and_more.py b/src/triage/migrations/0017_tooldefect_created_at_tooldefect_created_by_and_more.py index 78583e4..b2d72ad 100644 --- a/src/triage/migrations/0017_tooldefect_created_at_tooldefect_created_by_and_more.py +++ b/src/triage/migrations/0017_tooldefect_created_at_tooldefect_created_by_and_more.py @@ -16,7 +16,8 @@ class Migration(migrations.Migration): model_name="tooldefect", name="created_at", field=models.DateTimeField( - auto_now_add=True, default=django.utils.timezone.now + auto_now_add=True, + default=django.utils.timezone.now, ), preserve_default=False, ), diff --git a/src/triage/migrations/0026_alter_attachment_uuid_alter_case_uuid_and_more.py b/src/triage/migrations/0026_alter_attachment_uuid_alter_case_uuid_and_more.py index b4557e4..e6cd06c 100644 --- a/src/triage/migrations/0026_alter_attachment_uuid_alter_case_uuid_and_more.py +++ b/src/triage/migrations/0026_alter_attachment_uuid_alter_case_uuid_and_more.py @@ -15,84 +15,120 @@ class Migration(migrations.Migration): model_name="attachment", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="case", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="file", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="filter", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="finding", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="project", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="projectversion", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="scan", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="tool", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="tooldefect", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="wikiarticle", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), migrations.AlterField( model_name="wikiarticlerevision", name="uuid", field=models.UUIDField( - db_index=True, default=uuid.uuid4, editable=False, unique=True + db_index=True, + default=uuid.uuid4, + editable=False, + unique=True, ), ), ] diff --git a/src/triage/models/__init__.py b/src/triage/models/__init__.py index 9c2c2ed..92c9557 100644 --- a/src/triage/models/__init__.py +++ b/src/triage/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ This file is required so that individual modules can be referenced from files within this directory. diff --git a/src/triage/models/attachment.py b/src/triage/models/attachment.py index 8c10704..aa3b9f6 100644 --- a/src/triage/models/attachment.py +++ b/src/triage/models/attachment.py @@ -8,7 +8,10 @@ class Attachment(models.Model): uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) filename = models.CharField(max_length=1024) content = models.BinaryField() diff --git a/src/triage/models/case.py b/src/triage/models/case.py index 5d3c653..e88a50d 100644 --- a/src/triage/models/case.py +++ b/src/triage/models/case.py @@ -23,11 +23,16 @@ class CasePartner(models.TextChoices): NOT_SPECIFIED = "NS", _("Not Specified") uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) findings = models.ManyToManyField("Finding", related_name="cases") state = models.CharField( - max_length=2, choices=WorkItemState.choices, default=WorkItemState.NEW + max_length=2, + choices=WorkItemState.choices, + default=WorkItemState.NEW, ) title = models.CharField(max_length=1024) description = models.TextField(null=True, blank=True) diff --git a/src/triage/models/file.py b/src/triage/models/file.py index f6ad9b5..f19f559 100644 --- a/src/triage/models/file.py +++ b/src/triage/models/file.py @@ -31,12 +31,18 @@ class FileType(models.TextChoices): UNKNOWN = "U", _("Unknown") uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) name = models.CharField(max_length=512, db_index=True) path = models.CharField(max_length=4096, db_index=True) file_type = models.CharField( - max_length=16, db_index=True, choices=FileType.choices, default=FileType.UNKNOWN + max_length=16, + db_index=True, + choices=FileType.choices, + default=FileType.UNKNOWN, ) content_type = models.CharField(max_length=64, db_index=True, null=True, blank=True) file_key = models.CharField(max_length=64, db_index=True, null=True, blank=True) diff --git a/src/triage/models/filter.py b/src/triage/models/filter.py index c6782a5..d1fc2bf 100644 --- a/src/triage/models/filter.py +++ b/src/triage/models/filter.py @@ -34,7 +34,10 @@ class RuleType(models.TextChoices): PYTHON_FUNCTION = "PY", _("Python Function") uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) title = models.CharField(max_length=255, null=True, blank=True) condition = models.TextField(null=True, blank=True) diff --git a/src/triage/models/finding.py b/src/triage/models/finding.py index 19b42fa..563d09b 100644 --- a/src/triage/models/finding.py +++ b/src/triage/models/finding.py @@ -21,7 +21,7 @@ def get_queryset(self): WorkItemState.NEW, WorkItemState.ACTIVE, WorkItemState.NOT_SPECIFIED, - ] + ], ) ) @@ -104,15 +104,24 @@ def parse(cls, severity: str, strict: bool = False) -> "Finding.SeverityLevel": return cls.NOT_SPECIFIED uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) project_version = models.ForeignKey( - "ProjectVersion", on_delete=models.CASCADE, null=True, blank=True + "ProjectVersion", + on_delete=models.CASCADE, + null=True, + blank=True, ) title = models.CharField(max_length=1024, db_index=True) normalized_title = models.CharField( - max_length=1024, null=True, blank=True, db_index=True + max_length=1024, + null=True, + blank=True, + db_index=True, ) file = models.ForeignKey("File", null=True, blank=True, on_delete=models.SET_NULL) @@ -151,12 +160,19 @@ def parse(cls, severity: str, strict: bool = False) -> "Finding.SeverityLevel": ) tool = models.ForeignKey( - "Tool", null=True, blank=True, on_delete=models.SET_NULL, db_index=True + "Tool", + null=True, + blank=True, + on_delete=models.SET_NULL, + db_index=True, ) # Who the finding is currently assigned to assigned_to = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL + User, + null=True, + blank=True, + on_delete=models.SET_NULL, ) assigned_dt = models.DateTimeField(auto_now_add=True) diff --git a/src/triage/models/project.py b/src/triage/models/project.py index f24280d..fd8fba2 100644 --- a/src/triage/models/project.py +++ b/src/triage/models/project.py @@ -22,11 +22,17 @@ class Project(BaseTimestampedModel, BaseUserTrackedModel): """An abstract project undergoing analysis.""" uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) name = models.CharField(max_length=1024, db_index=True) package_url = models.CharField( - max_length=1024, null=True, blank=True, db_index=True + max_length=1024, + null=True, + blank=True, + db_index=True, ) metadata = models.JSONField(null=True) @@ -41,11 +47,17 @@ class ProjectVersion(BaseTimestampedModel, BaseUserTrackedModel): """A version of a project.""" uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) project = models.ForeignKey("Project", on_delete=models.CASCADE) package_url = models.CharField( - max_length=1024, null=True, blank=True, db_index=True + max_length=1024, + null=True, + blank=True, + db_index=True, ) files = models.ManyToManyField("File", blank=True, editable=True) metadata = models.JSONField(null=True) @@ -58,7 +70,9 @@ def get_absolute_url(self): @classmethod def get_or_create_from_package_url( - cls, package_url: PackageURL, created_by: User + cls, + package_url: PackageURL, + created_by: User, ) -> "ProjectVersion": """Retrieves or create a PackageVersion from the given package_url.""" if package_url is None: @@ -101,14 +115,15 @@ def download_source_code(self): ) if res.returncode != 0 or not os.listdir(temp_directory): logger.debug("Failed to load source for package %s", self.package_url) - raise IOError("Failed to download package") + raise OSError("Failed to download package") num_added = 0 for root, _, files in os.walk(temp_directory): for file in files: full_path = os.path.join(root, file) relative_path = full_path[len(temp_directory) + 1 :].replace( - "\\", "/" + "\\", + "/", ) with open(full_path, "rb") as f: @@ -117,7 +132,9 @@ def download_source_code(self): logger.debug("Adding [%s]", relative_path) file_key = file_manager.add_file( - content, relative_path, exist_ok=True + content, + relative_path, + exist_ok=True, ) # Files are unique by content, path, etc. diff --git a/src/triage/models/tool.py b/src/triage/models/tool.py index 8682a12..0911d74 100644 --- a/src/triage/models/tool.py +++ b/src/triage/models/tool.py @@ -19,13 +19,18 @@ class ToolType(models.TextChoices): OTHER = "OT", _("Other") uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) name = models.CharField(max_length=128) friendly_name = models.CharField(max_length=128, blank=True, null=True) version = models.CharField(max_length=64, null=True, blank=True) type = models.CharField( - max_length=2, choices=ToolType.choices, default=ToolType.NOT_SPECIFIED + max_length=2, + choices=ToolType.choices, + default=ToolType.NOT_SPECIFIED, ) active = models.BooleanField(default=True) diff --git a/src/triage/models/tool_defect.py b/src/triage/models/tool_defect.py index e61c061..1121fed 100644 --- a/src/triage/models/tool_defect.py +++ b/src/triage/models/tool_defect.py @@ -26,7 +26,7 @@ def get_queryset(self): WorkItemState.NEW, WorkItemState.ACTIVE, WorkItemState.NOT_SPECIFIED, - ] + ], ) ) @@ -38,16 +38,24 @@ class ToolDefect(BaseTimestampedModel, BaseUserTrackedModel): tool = models.ForeignKey(Tool, on_delete=models.CASCADE) uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) title = models.CharField(max_length=1024) description = models.TextField(null=True, blank=True) findings = models.ManyToManyField("Finding") state = models.CharField( - choices=WorkItemState.choices, max_length=2, default=WorkItemState.NEW + choices=WorkItemState.choices, + max_length=2, + default=WorkItemState.NEW, ) assigned_to = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL + User, + null=True, + blank=True, + on_delete=models.SET_NULL, ) priority = models.PositiveSmallIntegerField(default=0) notes = models.ManyToManyField(Note) diff --git a/src/triage/models/triage.py b/src/triage/models/triage.py index 53bb594..2dbaf25 100644 --- a/src/triage/models/triage.py +++ b/src/triage/models/triage.py @@ -23,7 +23,9 @@ class RuleType(models.TextChoices): PYTHON_FUNCTION = "PY", _("Python Function") event = models.CharField( - max_length=2, choices=TriageEvent.choices, default=TriageEvent.ON_FINDING_NEW + max_length=2, + choices=TriageEvent.choices, + default=TriageEvent.ON_FINDING_NEW, ) condition = models.TextField(max_length=2048, null=True, blank=True) action = models.TextField(max_length=2048, null=True, blank=True) @@ -32,5 +34,7 @@ class RuleType(models.TextChoices): priority = models.PositiveSmallIntegerField(default=1000) type = models.CharField( - max_length=2, choices=RuleType.choices, default=RuleType.PYTHON_FUNCTION + max_length=2, + choices=RuleType.choices, + default=RuleType.PYTHON_FUNCTION, ) diff --git a/src/triage/models/wiki.py b/src/triage/models/wiki.py index 6c83c81..d5ca67f 100644 --- a/src/triage/models/wiki.py +++ b/src/triage/models/wiki.py @@ -10,10 +10,15 @@ class WikiArticleRevision(BaseTimestampedModel, BaseUserTrackedModel): uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) article = models.ForeignKey( - "WikiArticle", on_delete=models.CASCADE, related_name="revisions" + "WikiArticle", + on_delete=models.CASCADE, + related_name="revisions", ) title = models.CharField(max_length=1024) content = models.TextField(null=True, blank=True) @@ -47,21 +52,29 @@ def get_queryset(self): WorkItemState.NEW, WorkItemState.ACTIVE, WorkItemState.NOT_SPECIFIED, - ] + ], ) ) class WikiArticle(models.Model): uuid = models.UUIDField( - default=uuid.uuid4, editable=False, db_index=True, unique=True + default=uuid.uuid4, + editable=False, + db_index=True, + unique=True, ) slug = models.SlugField(unique=True) state = models.CharField( - max_length=2, choices=WorkItemState.choices, default=WorkItemState.ACTIVE + max_length=2, + choices=WorkItemState.choices, + default=WorkItemState.ACTIVE, ) current = models.ForeignKey( - WikiArticleRevision, on_delete=models.CASCADE, null=True, blank=True + WikiArticleRevision, + on_delete=models.CASCADE, + null=True, + blank=True, ) active_wiki_articles = ActiveWikiArticleManager() diff --git a/src/triage/static/triage/images/icon-sourcegraph.com.svg b/src/triage/static/triage/images/icon-sourcegraph.com.svg index a5f3cb0..5bd2c5d 100644 --- a/src/triage/static/triage/images/icon-sourcegraph.com.svg +++ b/src/triage/static/triage/images/icon-sourcegraph.com.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/triage/static/triage/omega.js b/src/triage/static/triage/omega.js index a428b9d..ab72052 100644 --- a/src/triage/static/triage/omega.js +++ b/src/triage/static/triage/omega.js @@ -293,4 +293,4 @@ const IS_SUCCESS = (data) => { if (status === 'success') return true; if (status === 'ok' || status.startsWith('ok')) return true; return false; -} \ No newline at end of file +} diff --git a/src/triage/templates/triage/base.html b/src/triage/templates/triage/base.html index dbc46fa..7c38790 100644 --- a/src/triage/templates/triage/base.html +++ b/src/triage/templates/triage/base.html @@ -88,7 +88,7 @@ {% else %} Filters {% endif %} - + + @@ -143,7 +143,7 @@ - +