diff --git a/src/teamvault/apps/secrets/forms.py b/src/teamvault/apps/secrets/forms.py index fd57a115..b15ae69f 100644 --- a/src/teamvault/apps/secrets/forms.py +++ b/src/teamvault/apps/secrets/forms.py @@ -104,10 +104,12 @@ class PasswordForm(SecretForm): password = forms.CharField( required=False, ) - url = forms.URLField( + url = forms.CharField( + max_length=255, required=False, ) username = forms.CharField( + max_length=255, required=False, ) diff --git a/src/teamvault/apps/secrets/migrations/0007_auto_20150205_1918.py b/src/teamvault/apps/secrets/migrations/0007_auto_20150205_1918.py new file mode 100644 index 00000000..725a4123 --- /dev/null +++ b/src/teamvault/apps/secrets/migrations/0007_auto_20150205_1918.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import teamvault.apps.secrets.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('secrets', '0006_auto_20150124_1103'), + ] + + operations = [ + migrations.AlterField( + model_name='secret', + name='url', + field=models.CharField(blank=True, null=True, validators=[teamvault.apps.secrets.models.validate_url], max_length=255), + ), + ] diff --git a/src/teamvault/apps/secrets/models.py b/src/teamvault/apps/secrets/models.py index c5a4631a..71d55176 100644 --- a/src/teamvault/apps/secrets/models.py +++ b/src/teamvault/apps/secrets/models.py @@ -6,9 +6,8 @@ from cryptography.fernet import Fernet from django.conf import settings from django.contrib.auth.models import Group, User -from django.core.exceptions import PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.core.urlresolvers import reverse -from django.core.validators import URLValidator from django.db import models from django.http import Http404 from django.utils.timezone import now @@ -20,19 +19,11 @@ from .exceptions import PermissionError -# yummy monkey patch to relax overzealous URL validation -URLValidator.host_re = ( - r'[a-z' + URLValidator.ul + r'0-9]' + - r'(?:[a-z' + URLValidator.ul + r'0-9-\.]*' + - r'[a-z' + URLValidator.ul + r'0-9])?' -) -URLValidator.regex = re.compile( - r'^(?:[a-z0-9\.\-]*)://' - r'(?:\S+(?::\S*)?@)?' - r'(?:' + URLValidator.ipv4_re + '|' + URLValidator.ipv6_re + '|' + URLValidator.host_re + ')' - r'(?::\d{2,5})?' - r'(?:[/?#][^\s]*)?' - r'$', re.IGNORECASE) +def validate_url(value): + if not "://" in value or \ + value.startswith("javascript:") or \ + value.startswith("data:"): + raise ValidationError(_("invalid URL")) class AccessRequest(models.Model): @@ -253,9 +244,14 @@ class Secret(models.Model): choices=STATUS_CHOICES, default=STATUS_OK, ) - url = models.URLField( + url = models.CharField( blank=True, + max_length=255, null=True, + # Django's builtin URL validation is pretty strict to the point + # of rejecting perfectly good URLs, thus we roll our own very + # liberal validation + validators=[validate_url], ) username = models.CharField( blank=True,