Moving away from session storage for user email confirmation process
This commit is contained in:
parent
48c8d730c2
commit
c4151b7752
|
@ -36,7 +36,8 @@ REQUIREMENTS = {
|
|||
'pytz': 'pytz',
|
||||
'tinymce': 'django-tinymce==1.5.1b2',
|
||||
'longerusername': 'longerusername',
|
||||
'bs4': 'beautifulsoup4'
|
||||
'bs4': 'beautifulsoup4',
|
||||
'picklefield': 'django-picklefield==0.3.0',
|
||||
}
|
||||
|
||||
if platform.system() != 'Windows':
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'UserEmailVerifier'
|
||||
db.create_table('django_authopenid_useremailverifier', (
|
||||
('key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, primary_key=True)),
|
||||
('value', self.gf('picklefield.fields.PickledObjectField')()),
|
||||
('verified', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
))
|
||||
db.send_create_signal('django_authopenid', ['UserEmailVerifier'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'UserEmailVerifier'
|
||||
db.delete_table('django_authopenid_useremailverifier')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
|
||||
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
|
||||
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
|
||||
'email_signature': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
|
||||
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_fake': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'languages': ('django.db.models.fields.CharField', [], {'default': "'es-NI'", 'max_length': '128'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
|
||||
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
|
||||
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'show_marked_tags': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
|
||||
'social_sharing_mode': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
|
||||
'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'twitter_access_token': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256'}),
|
||||
'twitter_handle': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'django_authopenid.association': {
|
||||
'Meta': {'object_name': 'Association'},
|
||||
'assoc_type': ('django.db.models.fields.TextField', [], {'max_length': '64'}),
|
||||
'handle': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'issued': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'lifetime': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'secret': ('django.db.models.fields.TextField', [], {'max_length': '255'}),
|
||||
'server_url': ('django.db.models.fields.TextField', [], {'max_length': '2047'})
|
||||
},
|
||||
'django_authopenid.nonce': {
|
||||
'Meta': {'object_name': 'Nonce'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'salt': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'server_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'timestamp': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'django_authopenid.userassociation': {
|
||||
'Meta': {'unique_together': "(('user', 'provider_name'), ('openid_url', 'provider_name'))", 'object_name': 'UserAssociation'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_used_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'openid_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'provider_name': ('django.db.models.fields.CharField', [], {'default': "'unknown'", 'max_length': '64'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'django_authopenid.useremailverifier': {
|
||||
'Meta': {'object_name': 'UserEmailVerifier'},
|
||||
'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'primary_key': 'True'}),
|
||||
'value': ('picklefield.fields.PickledObjectField', [], {})
|
||||
},
|
||||
'django_authopenid.userpasswordqueue': {
|
||||
'Meta': {'object_name': 'UserPasswordQueue'},
|
||||
'confirm_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'new_password': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['django_authopenid']
|
|
@ -3,21 +3,24 @@ from django.conf import settings
|
|||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
|
||||
from picklefield.fields import PickledObjectField
|
||||
|
||||
import hashlib, random, sys, os, time
|
||||
|
||||
__all__ = ['Nonce', 'Association', 'UserAssociation',
|
||||
'UserPasswordQueueManager', 'UserPasswordQueue']
|
||||
__all__ = ['Nonce', 'Association', 'UserAssociation',
|
||||
'UserPasswordQueueManager', 'UserPasswordQueue',
|
||||
'UserEmailVerifier']
|
||||
|
||||
class Nonce(models.Model):
|
||||
""" openid nonce """
|
||||
server_url = models.CharField(max_length=255)
|
||||
timestamp = models.IntegerField()
|
||||
salt = models.CharField(max_length=40)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return u"Nonce: %s" % self.id
|
||||
|
||||
|
||||
|
||||
class Association(models.Model):
|
||||
""" association openid url and lifetime """
|
||||
server_url = models.TextField(max_length=2047)
|
||||
|
@ -26,19 +29,19 @@ class Association(models.Model):
|
|||
issued = models.IntegerField()
|
||||
lifetime = models.IntegerField()
|
||||
assoc_type = models.TextField(max_length=64)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return u"Association: %s, %s" % (self.server_url, self.handle)
|
||||
|
||||
class UserAssociation(models.Model):
|
||||
"""
|
||||
model to manage association between openid and user
|
||||
"""
|
||||
model to manage association between openid and user
|
||||
"""
|
||||
#todo: rename this field so that it sounds good for other methods
|
||||
#for exaple, for password provider this will hold password
|
||||
openid_url = models.CharField(blank=False, max_length=255)
|
||||
user = models.ForeignKey(User)
|
||||
#in the future this must be turned into an
|
||||
#in the future this must be turned into an
|
||||
#association with a Provider record
|
||||
#to hold things like login badge, etc
|
||||
provider_name = models.CharField(max_length=64, default='unknown')
|
||||
|
@ -49,7 +52,7 @@ class UserAssociation(models.Model):
|
|||
('user','provider_name'),
|
||||
('openid_url', 'provider_name')
|
||||
)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return "Openid %s with user %s" % (self.openid_url, self.user)
|
||||
|
||||
|
@ -82,3 +85,13 @@ class UserPasswordQueue(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return self.user.username
|
||||
|
||||
class UserEmailVerifier(models.Model):
|
||||
'''Model that stores the required values to verify an email
|
||||
address'''
|
||||
key = models.CharField(max_length=255, unique=True, primary_key=True)
|
||||
value = PickledObjectField()
|
||||
verified = models.BooleanField(default=False)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.key
|
||||
|
|
|
@ -81,7 +81,7 @@ import urllib
|
|||
from askbot import forms as askbot_forms
|
||||
from askbot.deps.django_authopenid import util
|
||||
from askbot.deps.django_authopenid import decorators
|
||||
from askbot.deps.django_authopenid.models import UserAssociation
|
||||
from askbot.deps.django_authopenid.models import UserAssociation, UserEmailVerifier
|
||||
from askbot.deps.django_authopenid import forms
|
||||
from askbot.deps.django_authopenid.backends import AuthBackend
|
||||
import logging
|
||||
|
@ -1019,12 +1019,13 @@ def register(request, login_provider_name=None, user_identifier=None):
|
|||
cleanup_post_register_session(request)
|
||||
return HttpResponseRedirect(next_url)
|
||||
else:
|
||||
request.session['username'] = username
|
||||
request.session['email'] = email
|
||||
key = generate_random_key()
|
||||
email = request.session['email']
|
||||
send_email_key(email, key, handler_url_name='verify_email_and_register')
|
||||
request.session['validation_code'] = key
|
||||
email_verifier = UserEmailVerifier(key=generate_random_key())
|
||||
email_verifier.value = {'username': username, 'email': email,
|
||||
'user_identifier': user_identifier,
|
||||
'login_provider_name': login_provider_name}
|
||||
email_verifier.save()
|
||||
send_email_key(email, email_verifier.key,
|
||||
handler_url_name='verify_email_and_register')
|
||||
redirect_url = reverse('verify_email_and_register') + '?next=' + next_url
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
||||
|
@ -1073,14 +1074,16 @@ def verify_email_and_register(request):
|
|||
try:
|
||||
#we get here with post if button is pushed
|
||||
#or with "get" if emailed link is clicked
|
||||
expected_code = request.session['validation_code']
|
||||
assert(presented_code == expected_code)
|
||||
#create an account!
|
||||
username = request.session['username']
|
||||
email = request.session['email']
|
||||
password = request.session.get('password', None)
|
||||
user_identifier = request.session.get('user_identifier', None)
|
||||
login_provider_name = request.session.get('login_provider_name', None)
|
||||
email_verifier = UserEmailVerifier.objects.get(key=presented_code)
|
||||
#verifies that the code has not been used already
|
||||
assert(email_verifier.verified == False)
|
||||
|
||||
username = email_verifier.value['username']
|
||||
email = email_verifier.value['email']
|
||||
password = email_verifier.value.get('password', None)
|
||||
user_identifier = email_verifier.value.get('user_identifier', None)
|
||||
login_provider_name = email_verifier.value.get('login_provider_name', None)
|
||||
|
||||
if password:
|
||||
user = create_authenticated_user_account(
|
||||
username=username,
|
||||
|
@ -1098,7 +1101,10 @@ def verify_email_and_register(request):
|
|||
raise NotImplementedError()
|
||||
|
||||
login(request, user)
|
||||
email_verifier.verified = True
|
||||
email_verifier.save()
|
||||
cleanup_post_register_session(request)
|
||||
|
||||
return HttpResponseRedirect(get_next_url(request))
|
||||
except Exception, e:
|
||||
message = _(
|
||||
|
@ -1159,14 +1165,13 @@ def signup_with_password(request):
|
|||
cleanup_post_register_session(request)
|
||||
return HttpResponseRedirect(get_next_url(request))
|
||||
else:
|
||||
request.session['username'] = username
|
||||
request.session['email'] = email
|
||||
request.session['password'] = password
|
||||
#todo: generate a key and save it in the session
|
||||
key = generate_random_key()
|
||||
email = request.session['email']
|
||||
send_email_key(email, key, handler_url_name='verify_email_and_register')
|
||||
request.session['validation_code'] = key
|
||||
email_verifier = UserEmailVerifier(key=generate_random_key())
|
||||
email_verifier.value = {'username': username,
|
||||
'login_provider_name': provider_name,
|
||||
'email': email, 'password': password}
|
||||
email_verifier.save()
|
||||
send_email_key(email, email_verifier.key,
|
||||
handler_url_name='verify_email_and_register')
|
||||
redirect_url = reverse('verify_email_and_register') + \
|
||||
'?next=' + get_next_url(request)
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
|
|
@ -23,3 +23,4 @@ sanction
|
|||
django-tinymce==1.5.1b2
|
||||
longerusername
|
||||
beautifulsoup4
|
||||
django-picklefield==0.3.0
|
||||
|
|
|
@ -27,3 +27,4 @@ sanction
|
|||
django-tinymce
|
||||
longerusername
|
||||
beautifulsoup4
|
||||
django-picklefield==0.3.0
|
||||
|
|
Reference in New Issue