summaryrefslogtreecommitdiffstats
path: root/askbot/deps
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-08-12 21:10:52 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-08-12 21:10:52 -0400
commit3759b85789d258ead2b09ff1653203e76166cd1c (patch)
tree21a17525e0c0a7e39fe415b4c8c04e302f7485a3 /askbot/deps
parentca2c6aa73f31ba1adb5dd62a416807773fb369f3 (diff)
downloadaskbot-3759b85789d258ead2b09ff1653203e76166cd1c.tar.gz
askbot-3759b85789d258ead2b09ff1653203e76166cd1c.tar.bz2
askbot-3759b85789d258ead2b09ff1653203e76166cd1c.zip
Added options to restrict email addresses and requirement to validate an email before joining the site
Diffstat (limited to 'askbot/deps')
-rw-r--r--askbot/deps/django_authopenid/urls.py7
-rw-r--r--askbot/deps/django_authopenid/util.py7
-rw-r--r--askbot/deps/django_authopenid/views.py346
3 files changed, 186 insertions, 174 deletions
diff --git a/askbot/deps/django_authopenid/urls.py b/askbot/deps/django_authopenid/urls.py
index f51939ab..cea0e78d 100644
--- a/askbot/deps/django_authopenid/urls.py
+++ b/askbot/deps/django_authopenid/urls.py
@@ -27,7 +27,12 @@ urlpatterns = patterns('askbot.deps.django_authopenid.views',
#but the setting is disabled right now
#url(r'^%s%s$' % (_('email/'), _('sendkey/')), 'send_email_key', name='send_email_key'),
#url(r'^%s%s(?P<id>\d+)/(?P<key>[\dabcdef]{32})/$' % (_('email/'), _('verify/')), 'verifyemail', name='user_verifyemail'),
- url(r'^%s(?P<key>[\dabcdef]{32})?$' % _('recover/'), 'account_recover', name='user_account_recover'),
+ url(r'^%s$' % _('recover/'), 'account_recover', name='user_account_recover'),
+ url(
+ r'^%s$' % _('verify-email/'),
+ 'verify_email_and_register',
+ name='verify_email_and_register'
+ ),
url(
r'^delete_login_method/$',#this method is ajax only
'delete_login_method',
diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py
index 28f6b2dd..9f02050d 100644
--- a/askbot/deps/django_authopenid/util.py
+++ b/askbot/deps/django_authopenid/util.py
@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
import cgi
import urllib
+import urllib2
import functools
import re
+import random
from openid.store.interface import OpenIDStore
from openid.association import Association as OIDAssociation
from openid.extensions import sreg
@@ -412,6 +414,7 @@ def get_enabled_major_login_providers():
token = oauth.Token(data['oauth_token'], data['oauth_token_secret'])
client = oauth.Client(consumer, token=token)
url = 'https://identi.ca/api/account/verify_credentials.json'
+ content = urllib2.urlopen(url).read()
json = simplejson.loads(content)
return json['id']
if askbot_settings.IDENTICA_KEY and askbot_settings.IDENTICA_SECRET:
@@ -848,3 +851,7 @@ def ldap_check_password(username, password):
except ldap.LDAPError, e:
logging.critical(unicode(e))
return False
+
+def generate_random_key():
+ random.seed()
+ return '%032x' % random.getrandbits(128)
diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py
index 2f80d366..642e59a3 100644
--- a/askbot/deps/django_authopenid/views.py
+++ b/askbot/deps/django_authopenid/views.py
@@ -80,15 +80,73 @@ from askbot.utils.forms import get_next_url
from askbot.utils.http import get_request_info
from askbot.models.signals import user_logged_in, user_registered
+def create_authenticated_user_account(
+ username=None, email=None, password=None,
+ user_identifier=None, login_provider_name=None, subscribe=False
+):
+ """creates a user account, user association with
+ the login method and the the default email subscriptions
+ """
+
+ user = User.objects.create_user(username, email)
+ user_registered.send(None, user=user)
+
+ logging.debug('creating new openid user association for %s')
+
+ if password:
+ user.set_password(password)
+ user.save()
+ else:
+ UserAssociation(
+ openid_url = user_identifier,
+ user = user,
+ provider_name = login_provider_name,
+ last_used_timestamp = datetime.datetime.now()
+ ).save()
+
+ subscribe_form = askbot_forms.SimpleEmailSubscribeForm(
+ {'subscribe': subscribe}
+ )
+ subscribe_form.full_clean()
+ logging.debug('saving email feed settings')
+ subscribe_form.save(user)
+
+ logging.debug('logging the user in')
+ user = authenticate(method='force', user_id=user.id)
+ if user is None:
+ error_message = 'please make sure that ' + \
+ 'askbot.deps.django_authopenid.backends.AuthBackend' + \
+ 'is in your settings.AUTHENTICATION_BACKENDS'
+ raise Exception(error_message)
+
+ return user
+
+
+def cleanup_post_register_session(request):
+ """delete keys from session after registration is complete"""
+ keys = (
+ 'user_identifier',
+ 'login_provider_name',
+ 'username',
+ 'email',
+ 'subscribe',
+ 'password',
+ 'validation_code'
+ )
+ for key in keys:
+ if key in request.session:
+ del request.session[key]
+
+
#todo: decouple from askbot
-def login(request,user):
+def login(request, user):
from django.contrib.auth import login as _login
# get old session key
session_key = request.session.session_key
# login and get new session key
- _login(request,user)
+ _login(request, user)
# send signal with old session key as argument
logging.debug('logged in user %s with session key %s' % (user.username, session_key))
@@ -270,7 +328,7 @@ def complete_oauth_signin(request):
def signin(request):
"""
signin page. It manages the legacy authentification (user/password)
- and openid authentification
+ and openid authentication
url: /signin/
@@ -782,7 +840,6 @@ def register(request, login_provider_name=None, user_identifier=None):
next_url = get_next_url(request)
user = None
- is_redirect = False
username = request.session.get('username', '')
email = request.session.get('email', '')
logging.debug('request method is %s' % request.method)
@@ -824,56 +881,32 @@ def register(request, login_provider_name=None, user_identifier=None):
logging.debug('SimpleEmailSubscribeForm is INVALID')
else:
logging.debug('OpenidRegisterForm and SimpleEmailSubscribeForm are valid')
- is_redirect = True
+
username = register_form.cleaned_data['username']
email = register_form.cleaned_data['email']
+ subscribe = email_feeds_form.cleaned_data['subscribe']
- user = User.objects.create_user(username, email)
- user_registered.send(None, user = user)
-
- logging.debug('creating new openid user association for %s')
-
- UserAssociation(
- openid_url = user_identifier,
- user = user,
- provider_name = login_provider_name,
- last_used_timestamp = datetime.datetime.now()
- ).save()
-
- del request.session['user_identifier']
- del request.session['login_provider_name']
-
- logging.debug('logging the user in')
-
- user = authenticate(method = 'force', user_id = user.id)
- if user is None:
- error_message = 'please make sure that ' + \
- 'askbot.deps.django_authopenid.backends.AuthBackend' + \
- 'is in your settings.AUTHENTICATION_BACKENDS'
- raise Exception(error_message)
-
- login(request, user)
-
- logging.debug('saving email feed settings')
- email_feeds_form.save(user)
+ if askbot_settings.REQUIRE_VALID_EMAIL_FOR == 'nothing':
- #check if we need to post a question that was added anonymously
- #this needs to be a function call becase this is also done
- #if user just logged in and did not need to create the new account
-
- if user != None:
- if askbot_settings.EMAIL_VALIDATION == True:
- logging.debug('sending email validation')
- send_new_email_key(user, nomessage=True)
- output = validation_email_sent(request)
- set_email_validation_message(user) #message set after generating view
- return output
- if user.is_authenticated():
- logging.debug('success, send user to main page')
- return HttpResponseRedirect(reverse('index'))
+ user = create_authenticated_user_account(
+ username=username,
+ email=email,
+ user_identifier=user_identifier,
+ login_provider_name=login_provider_name,
+ subscribe=subscribe
+ )
+ login(request, user)
+ cleanup_post_register_session(request)
+ return HttpResponseRedirect(next_url)
else:
- logging.debug('have really strange error')
- raise Exception('openid login failed')#should not ever get here
+ request.session['username'] = username
+ request.session['email'] = email
+ request.session['subscribe'] = subscribe
+ key = util.generate_random_key()
+ email = request.session['email']
+ send_email_key(email, key, handler_url_name='verify_email_and_register')
+ request.session['validation_code'] = key
+ return HttpResponseRedirect(reverse('verify_email_and_register'))
providers = {
'yahoo':'<font color="purple">Yahoo!</font>',
@@ -908,6 +941,61 @@ def signin_failure(request, message):
return show_signin_view(request)
@not_authenticated
+@csrf.csrf_protect
+def verify_email_and_register(request):
+ """for POST request - check the validation code,
+ and if correct - create an account an log in the user
+
+ for GET - give a field to paste the activation code
+ and a button to send another validation email.
+ """
+ presented_code = request.REQUEST.get('validation_code', None)
+ if presented_code:
+ 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)
+ subscribe = request.session['subscribe']
+ user_identifier = request.session.get('user_identifier', None)
+ login_provider_name = request.session.get('login_provider_name', None)
+ if password:
+ user = create_authenticated_user_account(
+ username=username,
+ email=email,
+ password=password,
+ subscribe=subscribe
+ )
+ elif user_identifier and login_provider_name:
+ user = create_authenticated_user_account(
+ username=username,
+ email=email,
+ user_identifier=user_identifier,
+ login_provider_name=login_provider_name,
+ subscribe=subscribe
+ )
+ else:
+ raise NotImplementedError()
+
+ login(request, user)
+ cleanup_post_register_session(request)
+ return HttpResponseRedirect(reverse('index'))
+ except Exception, e:
+ message = _(
+ 'Sorry, registration failed. '
+ 'Please ask the site administrator for help.'
+ )
+ request.user.message_set.create(message=message)
+ return HttpResponseRedirect(reverse('index'))
+ else:
+ data = {'page_class': 'validate-email-page'}
+ return render_into_skin('authopenid/verify_email.html', data, request)
+
+@not_authenticated
@decorators.valid_password_login_provider_required
@csrf.csrf_protect
@fix_recaptcha_remote_ip
@@ -950,42 +1038,30 @@ def signup_with_password(request):
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
- provider_name = form.cleaned_data['login_provider']
-
- new_user = User.objects.create_user(username, email, password)
- user_registered.send(None, user = new_user)
-
- logging.debug('new user %s created' % username)
- if provider_name != 'local':
- raise NotImplementedError('must run create external user code')
-
- user = authenticate(
- username = username,
- password = password,
- provider_name = provider_name,
- method = 'password'
- )
+ subscribe = email_feeds_form.cleaned_data['subscribe']
+
+ if askbot_settings.REQUIRE_VALID_EMAIL_FOR == 'nothing':
+ user = create_authenticated_user_account(
+ username=username,
+ email=email,
+ password=password,
+ subscribe=subscribe
+ )
+ login(request, user)
+ cleanup_post_register_session(request)
+ return HttpResponseRedirect(next)
+ else:
+ request.session['username'] = username
+ request.session['email'] = email
+ request.session['password'] = password
+ request.session['subscribe'] = subscribe
+ #todo: generate a key and save it in the session
+ key = util.generate_random_key()
+ email = request.session['email']
+ send_email_key(email, key, handler_url_name='verify_email_and_register')
+ request.session['validation_code'] = key
+ return HttpResponseRedirect(reverse('verify_email_and_register'))
- login(request, user)
- logging.debug('new user logged in')
- email_feeds_form.save(user)
- logging.debug('email feeds form saved')
-
- # send email
- #subject = _("Welcome email subject line")
- #message_template = get_emplate(
- # 'authopenid/confirm_email.txt'
- #)
- #message_context = Context({
- # 'signup_url': askbot_settings.APP_URL + reverse('user_signin'),
- # 'username': username,
- # 'password': password,
- #})
- #message = message_template.render(message_context)
- #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
- # [user.email])
- #logging.debug('new password acct created, confirmation email sent!')
- return HttpResponseRedirect(next)
else:
#todo: this can be solved with a decorator, maybe
form.initial['login_provider'] = provider_name
@@ -1055,89 +1131,35 @@ def xrdf(request):
return_to = "%s%s" % (url_host, reverse('user_complete_signin'))
return HttpResponse(XRDF_TEMPLATE % {'return_to': return_to})
-def find_email_validation_messages(user):
- msg_text = _('your email needs to be validated see %(details_url)s') \
- % {'details_url':reverse('faq') + '#validate'}
- return user.message_set.filter(message__exact=msg_text)
-
-def set_email_validation_message(user):
- messages = find_email_validation_messages(user)
- msg_text = _('your email needs to be validated see %(details_url)s') \
- % {'details_url':reverse('faq') + '#validate'}
- if len(messages) == 0:
- user.message_set.create(message=msg_text)
-
-def clear_email_validation_message(user):
- messages = find_email_validation_messages(user)
- messages.delete()
-
-def set_new_email(user, new_email, nomessage=False):
+def set_new_email(user, new_email):
if new_email != user.email:
user.email = new_email
user.email_isvalid = False
user.save()
- if askbot_settings.EMAIL_VALIDATION == True:
- send_new_email_key(user,nomessage=nomessage)
-def _send_email_key(user):
+def send_email_key(email, key, handler_url_name='user_account_recover'):
"""private function. sends email containing validation key
to user's email address
"""
- subject = _("Recover your %(site)s account") % {'site': askbot_settings.APP_SHORT_NAME}
+ subject = _("Recover your %(site)s account") % \
+ {'site': askbot_settings.APP_SHORT_NAME}
url = urlparse(askbot_settings.APP_URL)
data = {
'validation_link': url.scheme + '://' + url.netloc + \
- reverse(
- 'user_account_recover',
- kwargs={'key':user.email_key}
- )
+ reverse(handler_url_name) +\
+ '?validation_code=' + key
}
template = get_template('authopenid/email_validation.txt')
message = template.render(data)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
+ send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email])
-def send_new_email_key(user,nomessage=False):
- import random
- random.seed()
- user.email_key = '%032x' % random.getrandbits(128)
+def send_user_new_email_key(user):
+ user.email_key = util.generate_random_key()
user.save()
- _send_email_key(user)
- if nomessage==False:
- set_email_validation_message(user)
+ send_email_key(user.email, user.email_key)
-@login_required
-@csrf.csrf_protect
-def send_email_key(request):
- """
- url = /email/sendkey/
-
- view that is shown right after sending email key
- email sending is called internally
-
- raises 404 if email validation is off
- if current email is valid shows 'key_not_sent' view of
- authopenid/changeemail.html template
- """
- if askbot_settings.EMAIL_VALIDATION == True:
- if request.user.email_isvalid:
- data = {
- 'email': request.user.email,
- 'action_type': 'key_not_sent',
- 'change_link': reverse('user_changeemail')
- }
- return render_into_skin(
- 'authopenid/changeemail.html',
- data,
- request
- )
- else:
- send_new_email_key(request.user)
- return validation_email_sent(request)
- else:
- raise Http404
-
-def account_recover(request, key = None):
+def account_recover(request):
"""view similar to send_email_key, except
it allows user to recover an account by entering
his/her email address
@@ -1153,7 +1175,7 @@ def account_recover(request, key = None):
form = forms.AccountRecoveryForm(request.POST)
if form.is_valid():
user = form.cleaned_data['user']
- send_new_email_key(user, nomessage = True)
+ send_user_new_email_key(user)
message = _(
'Please check your email and visit the enclosed link.'
)
@@ -1168,6 +1190,7 @@ def account_recover(request, key = None):
account_recovery_form = form
)
else:
+ key = request.GET.get('validation_code', None)
if key is None:
return HttpResponseRedirect(reverse('user_signin'))
@@ -1201,26 +1224,3 @@ def validation_email_sent(request):
'action_type': 'validate'
}
return render_into_skin('authopenid/changeemail.html', data, request)
-
-def verifyemail(request,id=None,key=None):
- """
- view that is shown when user clicks email validation link
- url = /email/verify/{{user.id}}/{{user.email_key}}/
- """
- logging.debug('')
- if askbot_settings.EMAIL_VALIDATION == True:
- user = User.objects.get(id=id)
- if user:
- if user.email_key == key:
- user.email_isvalid = True
- clear_email_validation_message(user)
- user.save()
- data = {'action_type': 'validation_complete'}
- return render_into_skin(
- 'authopenid/changeemail.html',
- data,
- request
- )
- else:
- logging.error('hmm, no user found for email validation message - foul play?')
- raise Http404