diff --git a/config.py b/config.py index 324a4e0..15decaa 100644 --- a/config.py +++ b/config.py @@ -25,6 +25,7 @@ INSTALLED_APPS.extend([ 'anymail', 'ivatar', 'ivatar.ivataraccount', + 'ivatar.tools', ]) from ivatar.settings import MIDDLEWARE # noqa @@ -54,6 +55,9 @@ OPENID_UPDATE_DETAILS_FROM_SREG = True SITE_NAME = 'ivatar' IVATAR_VERSION = '0.1' +SECURE_BASE_URL = 'https://avatars.linux-kernel.at/avatar/' +BASE_URL = 'http://avatars.linux-kernel.at/avatar/' + LOGIN_REDIRECT_URL = reverse_lazy('profile') MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294 SERVER_EMAIL = 'accounts@mg.linux-kernel.at' @@ -65,6 +69,13 @@ MAX_PIXELS = 7000 AVATAR_MAX_SIZE = 512 JPEG_QUALITY = 85 +# I'm not 100% sure if single character domains are possible +# under any tld... so MIN_LENGTH_EMAIL/_URL, might be +1 +MIN_LENGTH_URL = 11 # eg. http://a.io +MAX_LENGTH_URL = 255 # MySQL can't handle more than that (LP: 1018682) +MIN_LENGTH_EMAIL = 6 # eg. x@x.xx +MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294 + BOOTSTRAP4 = { 'include_jquery': False, 'javascript_in_head': False, diff --git a/ivatar/ivataraccount/forms.py b/ivatar/ivataraccount/forms.py index 168d884..60c155c 100644 --- a/ivatar/ivataraccount/forms.py +++ b/ivatar/ivataraccount/forms.py @@ -12,7 +12,8 @@ from django.core.mail import send_mail from ipware import get_client_ip from ivatar import settings -from ivatar.settings import MAX_LENGTH_EMAIL +from ivatar.settings import MIN_LENGTH_EMAIL, MAX_LENGTH_EMAIL +from ivatar.settings import MIN_LENGTH_URL, MAX_LENGTH_URL from ivatar.ivataraccount.models import MAX_LENGTH_URL from . models import UnconfirmedEmail, ConfirmedEmail, Photo from . models import UnconfirmedOpenId, ConfirmedOpenId @@ -26,8 +27,8 @@ class AddEmailForm(forms.Form): ''' email = forms.EmailField( label=_('Email'), + min_length=MIN_LENGTH_EMAIL, max_length=MAX_LENGTH_EMAIL, - min_length=6, # x@x.xx ) def clean_email(self): @@ -136,10 +137,8 @@ class AddOpenIDForm(forms.Form): ''' openid = forms.URLField( label=_('OpenID'), + min_length=MIN_LENGTH_URL, max_length=MAX_LENGTH_URL, - # However, not 100% sure if single character domains are possible - # under any tld... - min_length=11, # eg. http://a.io initial='http://' ) diff --git a/ivatar/ivataraccount/models.py b/ivatar/ivataraccount/models.py index 7ff69eb..c282de7 100644 --- a/ivatar/ivataraccount/models.py +++ b/ivatar/ivataraccount/models.py @@ -365,6 +365,9 @@ class ConfirmedOpenId(BaseAccountModel): lowercase_url = urlunsplit( (url.scheme.lower(), netloc, url.path, url.query, url.fragment) ) + if lowercase_url[-1] != '/': + lowercase_url += '/' + self.openid = lowercase_url self.digest = hashlib.sha256(lowercase_url.encode('utf-8')).hexdigest() return super().save(force_insert, force_update, using, update_fields) diff --git a/ivatar/ivataraccount/test_views.py b/ivatar/ivataraccount/test_views.py index 5f1d133..7c99489 100644 --- a/ivatar/ivataraccount/test_views.py +++ b/ivatar/ivataraccount/test_views.py @@ -38,7 +38,7 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods password = random_string() email = '%s@%s.%s' % (username, random_string(), random_string(2)) # Dunno why random tld doens't work, but I'm too lazy now to investigate - openid = 'http://%s.%s.%s' % (username, random_string(), 'org') + openid = 'http://%s.%s.%s/' % (username, random_string(), 'org') def login(self): ''' @@ -822,7 +822,6 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods }, ) self.assertEqual(response.status_code, 302, 'OpenID must redirect') - response = self.client.post( reverse('add_openid'), { 'openid': self.openid, diff --git a/ivatar/tools/forms.py b/ivatar/tools/forms.py new file mode 100644 index 0000000..736bb1c --- /dev/null +++ b/ivatar/tools/forms.py @@ -0,0 +1,72 @@ +''' +Classes for our ivatar.tools.forms +''' +from django import forms +from django.utils.translation import ugettext_lazy as _ +from django.core.exceptions import ValidationError + +from ivatar.settings import AVATAR_MAX_SIZE +from ivatar.settings import MIN_LENGTH_URL, MAX_LENGTH_URL +from ivatar.settings import MIN_LENGTH_EMAIL, MAX_LENGTH_EMAIL + + +class CheckDomainForm(forms.Form): + ''' + Form handling domain check + ''' + can_distribute = forms.TextInput( + attrs={ + 'label': _('Domain'), + 'required': True, + 'error_messages': { + 'required': + _('Cannot check without a domain name.') + } + } + ) + + +class CheckForm(forms.Form): + ''' + Form handling check + ''' + mail = forms.EmailField( + label=_('E-Mail'), + required=False, + min_length=MIN_LENGTH_EMAIL, + max_length=MAX_LENGTH_EMAIL, + error_messages={ + 'required': + _('Cannot check without a domain name.') + }) + + openid = forms.CharField( + label=_('OpenID'), + required=False, + min_length=MIN_LENGTH_URL, + max_length=MAX_LENGTH_URL, + error_messages={ + 'required': + _('Cannot check without an openid name.') + }) + + size = forms.IntegerField( + label=_('Size'), + initial=80, + min_value=5, + max_value=AVATAR_MAX_SIZE, + required=True, + ) + + default_url = forms.URLField( + label=_('Default URL'), + required=False, + ) + + def clean(self): + self.cleaned_data = super().clean() + mail = self.cleaned_data.get('mail') + openid = self.cleaned_data.get('openid') + if not mail and not openid: + raise ValidationError(_('Either OpenID or mail must be specified')) + return self.cleaned_data diff --git a/ivatar/tools/templates/check.html b/ivatar/tools/templates/check.html new file mode 100644 index 0000000..97faab8 --- /dev/null +++ b/ivatar/tools/templates/check.html @@ -0,0 +1,75 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load bootstrap4 %} +{% load static %} + +{% block title %}{% trans 'Check e-mail or openid' %}{% endblock title %} + +{% block content %} + +
+ This is what the avatars will look like depending on the hash and protocol you use:
+
+ {% if mail_hash %}
+ MD5 hash (mail): {{ mail_hash }}
+ SHA256 hash (mail): {{ mail_hash256 }}
+ {% endif %}
+
+ {% if openid_hash %}
+ SHA256 hash (OpenID): {{ openid_hash }}
+ {% endif %}
+
+
+