Merge branch 'devel' into 'master'

Merge in tools and lint via devel

See merge request oliver/ivatar!22
This commit is contained in:
Oliver Falk
2018-07-03 13:40:39 +02:00
10 changed files with 132 additions and 38 deletions

View File

@@ -96,7 +96,7 @@ BOOTSTRAP4 = {
}, },
} }
if not 'test' in sys.argv and not 'collectstatic' in sys.argv: if 'test' not in sys.argv and 'collectstatic' not in sys.argv:
ANYMAIL = { # pragma: no cover ANYMAIL = { # pragma: no cover
'MAILGUN_API_KEY': os.environ['IVATAR_MAILGUN_API_KEY'], 'MAILGUN_API_KEY': os.environ['IVATAR_MAILGUN_API_KEY'],
'MAILGUN_SENDER_DOMAIN': os.environ['IVATAR_MAILGUN_SENDER_DOMAIN'], 'MAILGUN_SENDER_DOMAIN': os.environ['IVATAR_MAILGUN_SENDER_DOMAIN'],
@@ -108,7 +108,7 @@ try:
from ivatar.settings import DATABASES from ivatar.settings import DATABASES
except Exception: # pragma: no cover except Exception: # pragma: no cover
DATABASES = [] # pragma: no cover DATABASES = [] # pragma: no cover
if not 'default' in DATABASES: if 'default' not in DATABASES:
DATABASES['default'] = { # pragma: no cover DATABASES['default'] = { # pragma: no cover
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

View File

@@ -4,6 +4,7 @@ Default: useful variables for the base page templates.
from ipware import get_client_ip from ipware import get_client_ip
from ivatar.settings import IVATAR_VERSION, SITE_NAME, MAX_PHOTO_SIZE from ivatar.settings import IVATAR_VERSION, SITE_NAME, MAX_PHOTO_SIZE
from ivatar.settings import BASE_URL, SECURE_BASE_URL
def basepage(request): def basepage(request):
''' '''
@@ -20,4 +21,6 @@ def basepage(request):
context['site_name'] = SITE_NAME context['site_name'] = SITE_NAME
context['site_url'] = request.build_absolute_uri('/')[:-1] context['site_url'] = request.build_absolute_uri('/')[:-1]
context['max_file_size'] = MAX_PHOTO_SIZE context['max_file_size'] = MAX_PHOTO_SIZE
context['BASE_URL'] = BASE_URL
context['SECURE_BASE_URL'] = SECURE_BASE_URL
return context return context

View File

@@ -14,7 +14,6 @@ from ipware import get_client_ip
from ivatar import settings from ivatar import settings
from ivatar.settings import MIN_LENGTH_EMAIL, 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.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 UnconfirmedEmail, ConfirmedEmail, Photo
from . models import UnconfirmedOpenId, ConfirmedOpenId from . models import UnconfirmedOpenId, ConfirmedOpenId
@@ -59,13 +58,17 @@ class AddEmailForm(forms.Form):
# sent by this user already # sent by this user already
if UnconfirmedEmail.objects.filter( # pylint: disable=no-member if UnconfirmedEmail.objects.filter( # pylint: disable=no-member
user=user, email=self.cleaned_data['email']).exists(): user=user, email=self.cleaned_data['email']).exists():
self.add_error('email', _('Address already added, currently unconfirmed')) self.add_error(
'email',
_('Address already added, currently unconfirmed'))
return False return False
# Check whether or not the email is already confirmed by someone # Check whether or not the email is already confirmed by someone
if ConfirmedEmail.objects.filter( if ConfirmedEmail.objects.filter(
email=self.cleaned_data['email']).exists(): email=self.cleaned_data['email']).exists():
self.add_error('email', _('Address already confirmed (by someone else)')) self.add_error(
'email',
_('Address already confirmed (by someone else)'))
return False return False
unconfirmed = UnconfirmedEmail() unconfirmed = UnconfirmedEmail()
@@ -166,7 +169,9 @@ class AddOpenIDForm(forms.Form):
if UnconfirmedOpenId.objects.filter( # pylint: disable=no-member if UnconfirmedOpenId.objects.filter( # pylint: disable=no-member
openid=self.cleaned_data['openid']).exists(): openid=self.cleaned_data['openid']).exists():
self.add_error('openid', _('OpenID already added, but not confirmed yet!')) self.add_error(
'openid',
_('OpenID already added, but not confirmed yet!'))
return False return False
unconfirmed = UnconfirmedOpenId() unconfirmed = UnconfirmedOpenId()

View File

@@ -26,12 +26,10 @@ from openid.store.interface import OpenIDStore
from ivatar.settings import MAX_LENGTH_EMAIL, logger from ivatar.settings import MAX_LENGTH_EMAIL, logger
from ivatar.settings import MAX_PIXELS, AVATAR_MAX_SIZE, JPEG_QUALITY from ivatar.settings import MAX_PIXELS, AVATAR_MAX_SIZE, JPEG_QUALITY
from ivatar.settings import MIN_LENGTH_URL, MAX_LENGTH_URL
from .gravatar import get_photo as get_gravatar_photo from .gravatar import get_photo as get_gravatar_photo
MAX_LENGTH_URL = 255 # MySQL can't handle more than that (LP 1018682)
def file_format(image_type): def file_format(image_type):
''' '''
Helper method returning a 3 character long image type Helper method returning a 3 character long image type

View File

@@ -93,7 +93,7 @@ class AddEmailView(SuccessMessageMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
if not form.save(self.request): if not form.save(self.request):
return render(self.request, self.template_name, { 'form': form }) return render(self.request, self.template_name, {'form': form})
else: else:
messages.success(self.request, _('Address added successfully')) messages.success(self.request, _('Address added successfully'))
return super().form_valid(form) return super().form_valid(form)
@@ -372,7 +372,7 @@ class AddOpenIDView(SuccessMessageMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
openid_id = form.save(self.request.user) openid_id = form.save(self.request.user)
if not openid_id: if not openid_id:
return render(self.request, self.template_name, { 'form': form }) return render(self.request, self.template_name, {'form': form})
else: else:
messages.success(self.request, _('ID added successfully')) messages.success(self.request, _('ID added successfully'))
return HttpResponseRedirect( return HttpResponseRedirect(
@@ -548,13 +548,14 @@ class CropPhotoView(TemplateView):
if 'email' in request.POST: if 'email' in request.POST:
try: try:
email = ConfirmedEmail.objects.get(email=request.POST['email']) email = ConfirmedEmail.objects.get(email=request.POST['email'])
except: except Exception:
pass # Ignore automatic assignment pass # Ignore automatic assignment
if 'openid' in request.POST: if 'openid' in request.POST:
try: try:
openid = ConfirmedOpenId.objects.get(openid=request.POST['openid']) openid = ConfirmedOpenId.objects.get(
except: openid=request.POST['openid'])
pass # Ignore automatic assignment except Exception:
pass # Ignore automatic assignment
return photo.perform_crop(request, dimensions, email, openid) return photo.perform_crop(request, dimensions, email, openid)

View File

@@ -185,3 +185,7 @@ ul li {
.clear-both { .clear-both {
clear: both; clear: both;
} }
.fas, .fab {
color: #dbc40d;
}

View File

@@ -33,30 +33,89 @@
{% endif %} {% endif %}
</p> </p>
<ul class="horizontal-list avatar-list centered"> <ul class="horizontal-list avatar-list centered" style="font-size:smaller;">
{% if mailurl %} {% if mailurl %}
<li> <li>
<img src="{{ mailurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;"> <div style="float:left;">
<br/> <a href="{{ mailurl }}">
MD5 <img src="{{ mailurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px;">
<i class="fas fa-unlock" title="None-SSL connection (http)"></i>
<br/>
<i class="fas fa-at" title="mail: {{ form.mail.value }}"></i>
</div>
</div>
<br/>MD5
</li> </li>
<li> <li>
<img src="{{ mailurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;"> <div style="float:left;">
<br/> <a href="{{ mailurl_secure }}">
MD5 <img src="{% static 'img/https_lock.png' %}"> <img src="{{ mailurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px;">
<i class="fas fa-lock" title="Secure connection (https)"></i>
<br/>
<i class="fas fa-at" title="mail: {{ form.mail.value }}"></i>
</div>
</div>
<br/>MD5
</li>
<li>
<div style="float:left;">
<a href="{{ BASE_URL }}{{ mail_hash256 }}?s={{ size }}">
<img src="{{ BASE_URL }}{{ mail_hash256 }}?s={{ size }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px;">
<i class="fas fa-unlock" title="None-SSL connection (http)"></i>
<br/>
<i class="fas fa-at" title="mail: {{ form.mail.value }}"></i>
</div>
</div>
<br/>SHA256
</li>
<li>
<div style="float:left;">
<a href="{{ SECURE_BASE_URL }}{{ mail_hash256 }}?s={{ size }}">
<img src="{{ SECURE_BASE_URL }}{{ mail_hash256 }}?s={{ size }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px;">
<i class="fas fa-lock" title="Secure connection (https)"></i>
<br/>
<i class="fas fa-at" title="mail: {{ form.mail.value }}"></i>
</div>
</div>
<br/>SHA256
</li> </li>
{% endif %} {% endif %}
{% if openidurl %} {% if openidurl %}
<li> <li>
<img src="{{ openidurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;"> <div style="float:left;">
<br/> <a href="{{ openidurl }}">
SHA256 <img src="{{ openidurl }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px">
<i class="fas fa-unlock" title="None-SSL connection (http)"></i>
<br/>
<i class="fab fa-openid" title="openid: {{ form.openid.value }}"></i>
</div>
</div>
<br/>SHA256
</li> </li>
<li> <li>
<img src="{{ openidurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;"> <div style="float:left;">
<br/> <a href="{{ openidurl_secure }}">
SHA256 <img src="{% static 'img/https_lock.png' %}"> <img src="{{ openidurl_secure }}" style="max-width: {{ size }}px; max-height: {{ size }}px;">
</a>
<div style="float:inline-end; font-size:{% widthratio size 3 1 %}px">
<i class="fas fa-lock" title="Secure connection (http)"></i>
<br/>
<i class="fab fa-openid" title="openid: {{ form.openid.value }}"></i>
</div>
</div>
<br/>SHA256
</li> </li>
{% endif %} {% endif %}
</ul> </ul>

View File

@@ -48,11 +48,22 @@ class CheckView(FormView):
default_url = None default_url = None
if form.cleaned_data['mail']: if form.cleaned_data['mail']:
mailurl = libravatar_url(email=form.cleaned_data['mail'], size=form.cleaned_data['size'], default=default_url) 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 = 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 = libravatar_url(
mailurl_secure = mailurl_secure.replace(LIBRAVATAR_SECURE_BASE_URL, SECURE_BASE_URL) email=form.cleaned_data['mail'],
mail_hash = parse_user_identity(email=form.cleaned_data['mail'], openid=None)[0] 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 = hashlib.new('sha256')
hash_obj.update(form.cleaned_data['mail'].encode('utf-8')) hash_obj.update(form.cleaned_data['mail'].encode('utf-8'))
mail_hash256 = hash_obj.hexdigest() mail_hash256 = hash_obj.hexdigest()
@@ -60,11 +71,22 @@ class CheckView(FormView):
if form.cleaned_data['openid']: if form.cleaned_data['openid']:
if form.cleaned_data['openid'][-1] != '/': if form.cleaned_data['openid'][-1] != '/':
form.cleaned_data['openid'] += '/' form.cleaned_data['openid'] += '/'
openidurl = libravatar_url(openid=form.cleaned_data['openid'], size=form.cleaned_data['size'], default=default_url) 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 = 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 = libravatar_url(
openidurl_secure = openidurl_secure.replace(LIBRAVATAR_SECURE_BASE_URL, SECURE_BASE_URL) openid=form.cleaned_data['openid'],
openid_hash = parse_user_identity(openid=form.cleaned_data['openid'], email=None)[0] 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'] size = form.cleaned_data['size']
return render(self.request, self.template_name, { return render(self.request, self.template_name, {

View File

@@ -22,7 +22,8 @@ class AvatarImageView(TemplateView):
# Fetch by digest from mail # Fetch by digest from mail
pass pass
elif len(kwargs['digest']) == 64: elif len(kwargs['digest']) == 64:
if ConfirmedOpenId.objects.filter(digest=kwargs['digest']).count(): # pylint: disable=no-member if ConfirmedOpenId.objects.filter(
digest=kwargs['digest']).count(): # pylint: disable=no-member
# Fetch by digest from OpenID # Fetch by digest from OpenID
model = ConfirmedOpenId model = ConfirmedOpenId
else: # pragma: no cover else: # pragma: no cover

View File

@@ -19,6 +19,7 @@
<link rel="icon" type="image/png" href="{% static '/img/nobody/195.png' %}" sizes="195x195"> <link rel="icon" type="image/png" href="{% static '/img/nobody/195.png' %}" sizes="195x195">
<link rel="mask-icon" href="{% static '/img/safari-pinned-tab.svg' %}" color="#fa711f"> <link rel="mask-icon" href="{% static '/img/safari-pinned-tab.svg' %}" color="#fa711f">
<link rel="stylesheet" href="{% static '/css/ivatar.css' %}" type="text/css"> <link rel="stylesheet" href="{% static '/css/ivatar.css' %}" type="text/css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileImage" content="{% static '/img/nobody/144.png' %}"> <meta name="msapplication-TileImage" content="{% static '/img/nobody/144.png' %}">
<meta name="msapplication-TileColor" content="#fa711f"> <meta name="msapplication-TileColor" content="#fa711f">