Add functionality to check OpenID/mail; Size already works, default URL not (yet)

This commit is contained in:
Oliver Falk
2018-07-03 10:58:03 +02:00
parent 65d989d59f
commit 1a08887892
7 changed files with 136 additions and 8 deletions

View File

@@ -55,6 +55,9 @@ OPENID_UPDATE_DETAILS_FROM_SREG = True
SITE_NAME = 'ivatar' SITE_NAME = 'ivatar'
IVATAR_VERSION = '0.1' 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') LOGIN_REDIRECT_URL = reverse_lazy('profile')
MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294 MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294
SERVER_EMAIL = 'accounts@mg.linux-kernel.at' SERVER_EMAIL = 'accounts@mg.linux-kernel.at'
@@ -66,6 +69,13 @@ MAX_PIXELS = 7000
AVATAR_MAX_SIZE = 512 AVATAR_MAX_SIZE = 512
JPEG_QUALITY = 85 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 = { BOOTSTRAP4 = {
'include_jquery': False, 'include_jquery': False,
'javascript_in_head': False, 'javascript_in_head': False,

View File

@@ -12,7 +12,8 @@ from django.core.mail import send_mail
from ipware import get_client_ip from ipware import get_client_ip
from ivatar import settings 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 ivatar.ivataraccount.models import MAX_LENGTH_URL
from . models import UnconfirmedEmail, ConfirmedEmail, Photo from . models import UnconfirmedEmail, ConfirmedEmail, Photo
from . models import UnconfirmedOpenId, ConfirmedOpenId from . models import UnconfirmedOpenId, ConfirmedOpenId
@@ -26,8 +27,8 @@ class AddEmailForm(forms.Form):
''' '''
email = forms.EmailField( email = forms.EmailField(
label=_('Email'), label=_('Email'),
min_length=MIN_LENGTH_EMAIL,
max_length=MAX_LENGTH_EMAIL, max_length=MAX_LENGTH_EMAIL,
min_length=6, # x@x.xx
) )
def clean_email(self): def clean_email(self):
@@ -136,10 +137,8 @@ class AddOpenIDForm(forms.Form):
''' '''
openid = forms.URLField( openid = forms.URLField(
label=_('OpenID'), label=_('OpenID'),
min_length=MIN_LENGTH_URL,
max_length=MAX_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://' initial='http://'
) )

View File

@@ -365,6 +365,9 @@ class ConfirmedOpenId(BaseAccountModel):
lowercase_url = urlunsplit( lowercase_url = urlunsplit(
(url.scheme.lower(), netloc, url.path, url.query, url.fragment) (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() self.digest = hashlib.sha256(lowercase_url.encode('utf-8')).hexdigest()
return super().save(force_insert, force_update, using, update_fields) return super().save(force_insert, force_update, using, update_fields)

View File

@@ -5,6 +5,10 @@ from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError 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): class CheckDomainForm(forms.Form):
''' '''
@@ -29,6 +33,8 @@ class CheckForm(forms.Form):
mail = forms.EmailField( mail = forms.EmailField(
label=_('E-Mail'), label=_('E-Mail'),
required=False, required=False,
min_length=MIN_LENGTH_EMAIL,
max_length=MAX_LENGTH_EMAIL,
error_messages={ error_messages={
'required': 'required':
_('Cannot check without a domain name.') _('Cannot check without a domain name.')
@@ -37,6 +43,8 @@ class CheckForm(forms.Form):
openid = forms.CharField( openid = forms.CharField(
label=_('OpenID'), label=_('OpenID'),
required=False, required=False,
min_length=MIN_LENGTH_URL,
max_length=MAX_LENGTH_URL,
error_messages={ error_messages={
'required': 'required':
_('Cannot check without an openid name.') _('Cannot check without an openid name.')
@@ -45,8 +53,8 @@ class CheckForm(forms.Form):
size = forms.IntegerField( size = forms.IntegerField(
label=_('Size'), label=_('Size'),
initial=80, initial=80,
min_value=10, min_value=5,
max_value=160, max_value=AVATAR_MAX_SIZE,
required=True, required=True,
) )

View File

@@ -1,6 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% load bootstrap4 %} {% load bootstrap4 %}
{% load static %}
{% block title %}{% trans 'Check e-mail or openid' %}{% endblock title %} {% block title %}{% trans 'Check e-mail or openid' %}{% endblock title %}
@@ -18,4 +19,57 @@
</form> </form>
</div> </div>
{% if mailurl or openidurl %}
<p>
This is what the avatars will look like depending on the hash and protocol you use:<br/>
{% if mail_hash %}
MD5 hash (mail): {{ mail_hash }}<br/>
SHA256 hash (mail): {{ mail_hash256 }}<br/>
{% endif %}
{% if openid_hash %}
SHA256 hash (OpenID): {{ openid_hash }}<br/>
{% endif %}
</p>
<ul class="horizontal-list avatar-list centered">
{% if mailurl %}
<li>
<img src="{{ mailurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
<br/>
MD5
</li>
<li>
<img src="{{ mailurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
<br/>
MD5 <img src="{% static 'img/https_lock.png' %}">
</li>
{% endif %}
{% if openidurl %}
<li>
<img src="{{ openidurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
<br/>
SHA256
</li>
<li>
<img src="{{ openidurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
<br/>
SHA256 <img src="{% static 'img/https_lock.png' %}">
</li>
{% endif %}
</ul>
{% endif %}
{# Bad hack in order to have the images for sure inside our "outer" div box #}
<!-- Bad hack -->
{% if mailurl %}
<div style="height: {{ size }}px;">&nbsp;</div>
{% endif %}
{% if openidurl %}
<div style="height: {{ size }}px;">&nbsp;</div>
{% endif %}
<!-- End of bad hack -->
{% endblock content %} {% endblock content %}

View File

@@ -5,7 +5,13 @@ from django.views.generic.edit import FormView
from django.urls import reverse_lazy as reverse from django.urls import reverse_lazy as reverse
from django.shortcuts import render from django.shortcuts import render
from libravatar import libravatar_url, parse_user_identity
from libravatar import SECURE_BASE_URL as LIBRAVATAR_SECURE_BASE_URL
from libravatar import BASE_URL as LIBRAVATAR_BASE_URL
import hashlib
from .forms import CheckDomainForm, CheckForm from .forms import CheckDomainForm, CheckForm
from ivatar.settings import SECURE_BASE_URL, BASE_URL
class CheckDomainView(FormView): class CheckDomainView(FormView):
@@ -25,5 +31,50 @@ class CheckView(FormView):
success_url = reverse('tools_check') success_url = reverse('tools_check')
def form_valid(self, form): def form_valid(self, form):
mailurl = None
openidurl = None
mailurl_secure = None
openidurl_secure = None
mail_hash = None
mail_hash256 = None
openid_hash = None
size = 80
super().form_valid(form) super().form_valid(form)
return render(self.request, self.template_name, {'form': form})
if form.cleaned_data['default_url']:
default_url = form.cleaned_data['default_url']
else:
default_url = None
if form.cleaned_data['mail']:
mailurl = libravatar_url(email=form.cleaned_data['mail'], size=form.cleaned_data['size'], default=default_url)
mailurl = mailurl.replace(LIBRAVATAR_BASE_URL, BASE_URL)
mailurl_secure = libravatar_url(email=form.cleaned_data['mail'], size=form.cleaned_data['size'], https=True, default=default_url)
mailurl_secure = mailurl_secure.replace(LIBRAVATAR_SECURE_BASE_URL, SECURE_BASE_URL)
mail_hash = parse_user_identity(email=form.cleaned_data['mail'], openid=None)[0]
hash_obj = hashlib.new('sha256')
hash_obj.update(form.cleaned_data['mail'].encode('utf-8'))
mail_hash256 = hash_obj.hexdigest()
size = form.cleaned_data['size']
if form.cleaned_data['openid']:
if form.cleaned_data['openid'][-1] != '/':
form.cleaned_data['openid'] += '/'
openidurl = libravatar_url(openid=form.cleaned_data['openid'], size=form.cleaned_data['size'], default=default_url)
openidurl = openidurl.replace(LIBRAVATAR_BASE_URL, BASE_URL)
openidurl_secure = libravatar_url(openid=form.cleaned_data['openid'], size=form.cleaned_data['size'], https=True, default=default_url)
openidurl_secure = openidurl_secure.replace(LIBRAVATAR_SECURE_BASE_URL, SECURE_BASE_URL)
openid_hash = parse_user_identity(openid=form.cleaned_data['openid'], email=None)[0]
size = form.cleaned_data['size']
return render(self.request, self.template_name, {
'form': form,
'mailurl': mailurl,
'openidurl': openidurl,
'mailurl_secure': mailurl_secure,
'openidurl_secure': openidurl_secure,
'mail_hash': mail_hash,
'mail_hash256': mail_hash256,
'openid_hash': openid_hash,
'size': size,
})

View File

@@ -19,13 +19,16 @@
</div> </div>
{% autoescape off %}{% bootstrap_messages %}{% endautoescape %} {% autoescape off %}{% bootstrap_messages %}{% endautoescape %}
{# TODO: Fix URLs!!! #}
<div id="account"> <div id="account">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a href="{% url 'profile' %}">{% trans 'Profile' %}</a>&nbsp;|&nbsp; <a href="{% url 'profile' %}">{% trans 'Profile' %}</a>&nbsp;|&nbsp;
<a href="{% url 'tools_check' %}">{% trans 'Check' %}</a>&nbsp;|&nbsp;
<a href="{{ contact_us }}">{% trans 'Contact Us' %}</a>&nbsp;|&nbsp; <a href="{{ contact_us }}">{% trans 'Contact Us' %}</a>&nbsp;|&nbsp;
<a href="{{ security_url }}">{% trans 'Security' %}</a>&nbsp;|&nbsp; <a href="{{ security_url }}">{% trans 'Security' %}</a>&nbsp;|&nbsp;
<a href="{% url 'logout' %}" id="logout-link">{% trans 'Logout' %}</a> <a href="{% url 'logout' %}" id="logout-link">{% trans 'Logout' %}</a>
{% else %} {% else %}
<a href="{% url 'tools_check' %}">{% trans 'Check' %}</a>&nbsp;|&nbsp;
<a href="{{ contact_us }}">{% trans 'Contact Us' %}</a>&nbsp;|&nbsp; <a href="{{ contact_us }}">{% trans 'Contact Us' %}</a>&nbsp;|&nbsp;
<a href="{{ security_url }}">{% trans 'Security' %}</a>&nbsp;|&nbsp; <a href="{{ security_url }}">{% trans 'Security' %}</a>&nbsp;|&nbsp;
<a href="{% url 'login' %}">{% trans 'Login' %}</a> <a href="{% url 'login' %}">{% trans 'Login' %}</a>