Commit b11495d0 authored by Oliver Falk's avatar Oliver Falk

In order to fix the reoccuring issue that OpenID users have to add several...

In order to fix the reoccuring issue that OpenID users have to add several different OpenID variations, we'll save the usual variations now in different digest fields -> should ease the pain a lot
parent 94bd528b
'''
''' yes
Configuration overrides for settings.py
'''
......@@ -52,7 +52,7 @@ OPENID_CREATE_USERS = True
OPENID_UPDATE_DETAILS_FROM_SREG = True
SITE_NAME = os.environ.get('SITE_NAME', 'libravatar')
IVATAR_VERSION = '1.2'
IVATAR_VERSION = '1.3'
SECURE_BASE_URL = os.environ.get('SECURE_BASE_URL', 'https://avatars.linux-kernel.at/avatar/')
BASE_URL = os.environ.get('BASE_URL', 'http://avatars.linux-kernel.at/avatar/')
......
# Generated by Django 3.0.3 on 2020-02-25 09:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ivataraccount', '0014_auto_20190218_1602'),
]
operations = [
migrations.AddField(
model_name='confirmedopenid',
name='alt_digest1',
field=models.CharField(blank=True, default=None, max_length=64, null=True),
),
migrations.AddField(
model_name='confirmedopenid',
name='alt_digest2',
field=models.CharField(blank=True, default=None, max_length=64, null=True),
),
migrations.AddField(
model_name='confirmedopenid',
name='alt_digest3',
field=models.CharField(blank=True, default=None, max_length=64, null=True),
),
]
......@@ -32,6 +32,7 @@ from ivatar.settings import MAX_LENGTH_EMAIL, logger
from ivatar.settings import MAX_PIXELS, AVATAR_MAX_SIZE, JPEG_QUALITY
from ivatar.settings import MAX_LENGTH_URL
from ivatar.settings import SECURE_BASE_URL, SITE_NAME, DEFAULT_FROM_EMAIL
from ivatar.utils import openid_variations
from .gravatar import get_photo as get_gravatar_photo
......@@ -422,7 +423,15 @@ class ConfirmedOpenId(BaseAccountModel):
null=True,
on_delete=models.deletion.SET_NULL,
)
# http://<id>/ base version - http w/ trailing slash
digest = models.CharField(max_length=64)
# http://<id> - http w/o trailing slash
alt_digest1 = models.CharField(max_length=64, null=True, blank=True, default=None)
# https://<id>/ - https w/ trailing slash
alt_digest2 = models.CharField(max_length=64, null=True, blank=True, default=None)
# https://<id> - https w/o trailing slash
alt_digest3 = models.CharField(max_length=64, null=True, blank=True, default=None)
access_count = models.BigIntegerField(default=0, editable=False)
class Meta: # pylint: disable=too-few-public-methods
......@@ -450,10 +459,13 @@ 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()
self.digest = hashlib.sha256(openid_variations(lowercase_url)[0].encode('utf-8')).hexdigest()
self.alt_digest1 = hashlib.sha256(openid_variations(lowercase_url)[1].encode('utf-8')).hexdigest()
self.alt_digest2 = hashlib.sha256(openid_variations(lowercase_url)[2].encode('utf-8')).hexdigest()
self.alt_digest3 = hashlib.sha256(openid_variations(lowercase_url)[3].encode('utf-8')).hexdigest()
return super().save(force_insert, force_update, using, update_fields)
def __str__(self):
......
'''
Test our utils from ivatar.utils
'''
from django.test import TestCase
from ivatar.utils import openid_variations
class Tester(TestCase):
'''
Main test class
'''
def test_openid_variations(self):
'''
Test if the OpenID variation "generator" does the correct thing
'''
openid0 = 'http://user.url/'
openid1 = 'http://user.url'
openid2 = 'https://user.url/'
openid3 = 'https://user.url'
# First variation
self.assertEqual(openid_variations(openid0)[0], openid0)
self.assertEqual(openid_variations(openid0)[1], openid1)
self.assertEqual(openid_variations(openid0)[2], openid2)
self.assertEqual(openid_variations(openid0)[3], openid3)
# Second varitations
self.assertEqual(openid_variations(openid1)[0], openid0)
self.assertEqual(openid_variations(openid1)[1], openid1)
self.assertEqual(openid_variations(openid1)[2], openid2)
self.assertEqual(openid_variations(openid1)[3], openid3)
# Third varitations
self.assertEqual(openid_variations(openid2)[0], openid0)
self.assertEqual(openid_variations(openid2)[1], openid1)
self.assertEqual(openid_variations(openid2)[2], openid2)
self.assertEqual(openid_variations(openid2)[3], openid3)
# Forth varitations
self.assertEqual(openid_variations(openid3)[0], openid0)
self.assertEqual(openid_variations(openid3)[1], openid1)
self.assertEqual(openid_variations(openid3)[2], openid2)
self.assertEqual(openid_variations(openid3)[3], openid3)
......@@ -11,3 +11,25 @@ def random_string(length=10):
'''
return ''.join(random.SystemRandom().choice(
string.ascii_lowercase + string.digits) for _ in range(length))
def openid_variations(openid):
'''
Return the various OpenID variations, ALWAYS in the same order:
- http w/ trailing slash
- http w/o trailing slash
- https w/ trailing slash
- https w/o trailing slash
'''
# Make the 'base' version: http w/ trailing slash
if openid.startswith('https://'):
openid = openid.replace('https://', 'http://')
if openid[-1] != '/':
openid = openid + '/'
# http w/o trailing slash
var1 = openid[0:-1]
var2 = openid.replace('http://', 'https://')
var3 = var2[0:-1]
return (openid, var1, var2, var3)
......@@ -12,6 +12,7 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _
from django.urls import reverse_lazy
from django.db.models import Q
from PIL import Image
......@@ -109,7 +110,15 @@ class AvatarImageView(TemplateView):
except ObjectDoesNotExist:
model = ConfirmedOpenId
try:
obj = model.objects.get(digest=kwargs['digest'])
d = kwargs['digest']
# OpenID is tricky. http vs. https, versus trailing slash or not
# However, some users eventually have added their variations already
# and therfore we need to use filter() and first()
obj = model.objects.filter(
Q(digest=d) |
Q(alt_digest1=d) |
Q(alt_digest2=d) |
Q(alt_digest3=d)).first()
except:
pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment