From 7e58f77294aa4543b86f55bceee2d91d90679fa8 Mon Sep 17 00:00:00 2001 From: Oliver Falk Date: Tue, 22 May 2018 14:39:37 +0200 Subject: [PATCH] Digest for ConfirmedEmail and ConfirmedOpenId --- .../migrations/0005_auto_20180522_1155.py | 25 ++++++++++ ivatar/ivataraccount/models.py | 49 ++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ivatar/ivataraccount/migrations/0005_auto_20180522_1155.py diff --git a/ivatar/ivataraccount/migrations/0005_auto_20180522_1155.py b/ivatar/ivataraccount/migrations/0005_auto_20180522_1155.py new file mode 100644 index 0000000..917c34f --- /dev/null +++ b/ivatar/ivataraccount/migrations/0005_auto_20180522_1155.py @@ -0,0 +1,25 @@ +# Generated by Django 2.0.5 on 2018-05-22 11:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ivataraccount', '0004_auto_20180508_0742'), + ] + + operations = [ + migrations.AddField( + model_name='confirmedemail', + name='digest', + field=models.CharField(default='', max_length=64), + preserve_default=False, + ), + migrations.AddField( + model_name='confirmedopenid', + name='digest', + field=models.CharField(default='', max_length=64), + preserve_default=False, + ), + ] diff --git a/ivatar/ivataraccount/models.py b/ivatar/ivataraccount/models.py index 15eb754..2a48b7b 100644 --- a/ivatar/ivataraccount/models.py +++ b/ivatar/ivataraccount/models.py @@ -1,3 +1,7 @@ +''' +Our models for ivatar.ivataraccount +''' + import base64 import hashlib import time @@ -5,6 +9,7 @@ from io import BytesIO from os import urandom from urllib.error import HTTPError, URLError from urllib.request import urlopen +from urllib.parse import urlsplit, urlunsplit from PIL import Image from django.contrib.auth.models import User @@ -15,8 +20,8 @@ from openid.association import Association as OIDAssociation from openid.store import nonce as oidnonce from openid.store.interface import OpenIDStore -from .gravatar import get_photo as get_gravatar_photo from ivatar.settings import MAX_LENGTH_EMAIL +from .gravatar import get_photo as get_gravatar_photo MAX_LENGTH_URL = 255 # MySQL can't handle more than that (LP 1018682) @@ -49,6 +54,9 @@ class BaseAccountModel(models.Model): add_date = models.DateTimeField(default=timezone.now) class Meta: + ''' + Class attributes + ''' abstract = True @@ -61,6 +69,9 @@ class Photo(BaseAccountModel): format = models.CharField(max_length=3) class Meta: + ''' + Class attributes + ''' verbose_name = _('photo') verbose_name_plural = _('photos') @@ -95,12 +106,16 @@ class Photo(BaseAccountModel): self.format = file_format(img.format) if not self.format: + print('Unable to determine format: %s' % img) return False self.data = data super().save() return True def save(self, *args, **kwargs): + ''' + Override save from parent, taking care about the image + ''' # Use PIL to read the file format try: img = Image.open(BytesIO(self.data)) @@ -121,6 +136,9 @@ class ConfirmedEmailManager(models.Manager): ''' def create_confirmed_email(self, user, email_address, is_logged_in): + ''' + Helper method to create confirmed email address + ''' confirmed = ConfirmedEmail() confirmed.user = user confirmed.ip_address = '0.0.0.0' @@ -149,16 +167,30 @@ class ConfirmedEmail(BaseAccountModel): null=True, on_delete=models.deletion.CASCADE, ) + digest = models.CharField(max_length=64) objects = ConfirmedEmailManager() class Meta: + ''' + Class attributes + ''' verbose_name = _('confirmed email') verbose_name_plural = _('confirmed emails') def set_photo(self, photo): + ''' + Helper method to set photo + ''' self.photo = photo self.save() + def save(self, *args, **kwargs): + ''' + Override save from parent, add digest + ''' + self.digest = hashlib.md5(self.email.strip().lower().encode('utf-8')).hexdigest() + return super().save(*args, **kwargs) + class UnconfirmedEmail(BaseAccountModel): ''' @@ -168,6 +200,9 @@ class UnconfirmedEmail(BaseAccountModel): verification_key = models.CharField(max_length=64) class Meta: + ''' + Class attributes + ''' verbose_name = _('unconfirmed_email') verbose_name_plural = _('unconfirmed_emails') @@ -202,6 +237,7 @@ class ConfirmedOpenId(BaseAccountModel): null=True, on_delete=models.deletion.CASCADE, ) + digest = models.CharField(max_length=64) class Meta: verbose_name = _('confirmed OpenID') @@ -211,6 +247,17 @@ class ConfirmedOpenId(BaseAccountModel): self.photo = photo self.save() + def save(self, *args, **kwargs): + url = urlsplit(self.openid) + if url.username: + password = url.password or '' + netloc = url.username + ':' + password + '@' + url.hostname + else: + netloc = url.hostname + lowercase_url = urlunsplit((url.scheme.lower(), netloc, url.path, url.query, url.fragment)) + self.digest = hashlib.sha256(lowercase_url.encode('utf-8')).hexdigest() + return super().save(*args, **kwargs) + class OpenIDNonce(models.Model): '''