diff --git a/api/Dockerfile b/api/Dockerfile index 15f0d67e..cce0f4fc 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -22,6 +22,9 @@ ENV HOME=/home/outdated ENV PYTHONUNBUFFERED=1 ENV DJANGO_SETTINGS_MODULE outdated.settings + +# prevent git from asking for credentials on wrong urls +ENV GIT_ASKPASS true ENV APP_HOME=/app COPY pyproject.toml poetry.lock $APP_HOME/ diff --git a/api/outdated/models.py b/api/outdated/models.py index 61b369bb..34694642 100644 --- a/api/outdated/models.py +++ b/api/outdated/models.py @@ -15,7 +15,10 @@ class Meta: class RepositoryURLField(models.URLField): - default_validators = [validators.RepositoryURLValidator()] + default_validators = [ + validators.RepositoryURLValidator(), + validators.validate_repo_exists, + ] class UniqueBooleanField(models.BooleanField): diff --git a/api/outdated/outdated/models.py b/api/outdated/outdated/models.py index 233f45c0..dd70df7c 100644 --- a/api/outdated/outdated/models.py +++ b/api/outdated/outdated/models.py @@ -1,6 +1,7 @@ from datetime import date, timedelta from os.path import basename, dirname +from django.core.exceptions import ValidationError from django.db import models from django.db.models.functions import Lower @@ -93,9 +94,17 @@ def version(self): return f"{self.release_version.version}.{self.patch_version}" +def repo_url_unique(value: str): + existing_urls = [p.clone_path for p in Project.objects.all()] + if Project(repo=value).clone_path in existing_urls: + raise ValidationError( + "Repository already exists.", params={"value": value}, code="unique" + ) + + class Project(UUIDModel): name = models.CharField(max_length=100, db_index=True) - repo = RepositoryURLField(unique=True) + repo = RepositoryURLField(unique=True, validators=[repo_url_unique]) versioned_dependencies = models.ManyToManyField(Version, blank=True) class Meta: diff --git a/api/outdated/validators.py b/api/outdated/validators.py index c450d11d..bac7446f 100644 --- a/api/outdated/validators.py +++ b/api/outdated/validators.py @@ -1,4 +1,6 @@ -from django.core.validators import RegexValidator +from subprocess import run + +from django.core.validators import RegexValidator, ValidationError from django.utils.deconstruct import deconstructible @@ -6,3 +8,10 @@ class RepositoryURLValidator(RegexValidator): regex = r"(http[s]?)(://)([\w\.@\:/\-~]+)(\.git)" message = "Enter a valid http or https url to a git repository." + + +def validate_repo_exists(value: str): + """Validate the existance of a remote git repository""" + result = run(["git", "ls-remote", value], capture_output=True) + if result.returncode != 0: + raise ValidationError("Repository does not exist.", params={"value": value})