diff options
author | hrcerqueira <hrcerqueira@gmail.com> | 2010-03-03 16:05:46 +0000 |
---|---|---|
committer | hrcerqueira <hrcerqueira@gmail.com> | 2010-03-03 16:05:46 +0000 |
commit | ec71d0c85766da2f9c369d2dc92c83d2a25cd22d (patch) | |
tree | 471a930a2e551846902300958dc5435233fd8d0c /forum/views | |
parent | 1d35d25b8ce9f3004eebd10d88757c5921dd686c (diff) | |
download | askbot-ec71d0c85766da2f9c369d2dc92c83d2a25cd22d.tar.gz askbot-ec71d0c85766da2f9c369d2dc92c83d2a25cd22d.tar.bz2 askbot-ec71d0c85766da2f9c369d2dc92c83d2a25cd22d.zip |
Temp login token request (for password recovery and google openid problems)
Utilities to send html emails, a base html email template and template tags to build full urls with domain name and protocol (for html email images and styles)
Email validation now uses an improved algorithm
Fixed a bug in the user message system
Diffstat (limited to 'forum/views')
-rwxr-xr-x | forum/views/auth.py | 181 | ||||
-rwxr-xr-x | forum/views/users.py | 33 |
2 files changed, 160 insertions, 54 deletions
diff --git a/forum/views/auth.py b/forum/views/auth.py index 6fe184a8..20e208ae 100755 --- a/forum/views/auth.py +++ b/forum/views/auth.py @@ -1,17 +1,21 @@ -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.core.urlresolvers import reverse from django.contrib.auth.models import User -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, Http404 from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ +from django.utils.http import urlquote_plus from django.contrib.auth.decorators import login_required from django.contrib.auth import login, logout from django.http import get_host import types +import datetime -from forum.models import AuthKeyUserAssociation -from forum.authentication.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm +from forum.models import AuthKeyUserAssociation, ValidationHash +from forum.authentication.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm, \ + TemporaryLoginRequestForm, ChangePasswordForm, SetPasswordForm +from forum.utils.email import send_email from forum.authentication.base import InvalidAuthentication from forum.authentication import AUTH_PROVIDERS @@ -105,8 +109,13 @@ def process_provider_signin(request, provider): except: uassoc = AuthKeyUserAssociation(user=request.user, key=assoc_key, provider=provider) uassoc.save() - request.session['auth_error'] = _("These new credentials are now associated with your account.") + request.user.message_set.create(message=_('The new credentials are now associated with your account')) + return HttpResponseRedirect(reverse('user_authsettings')) + return HttpResponseRedirect(reverse('auth_signin')) + else: + if isinstance(assoc_key, (type, User)): + return login_and_forward(request, assoc_key) try: assoc = AuthKeyUserAssociation.objects.get(key=assoc_key) @@ -125,12 +134,15 @@ def external_register(request): email_feeds_form = SimpleEmailSubscribeForm(request.POST) if (form1.is_valid() and email_feeds_form.is_valid()): - tmp_pwd = User.objects.make_random_password() - user_ = User.objects.create_user(form1.cleaned_data['username'], - form1.cleaned_data['email'], tmp_pwd) - + user_ = User(username=form1.cleaned_data['username'], email=form1.cleaned_data['email']) + user_.email_isvalid = request.session.get('auth_validated_email', '') == form1.cleaned_data['email'] user_.set_unusable_password() + user_.save() + + if not user_.email_isvalid: + send_validation_email(user_) + try: assoc_key = request.session['assoc_key'] auth_provider = request.session['auth_provider'] @@ -145,7 +157,11 @@ def external_register(request): del request.session['assoc_key'] del request.session['auth_provider'] - return login_and_forward(request, user_) + + if user_.email_isvalid: + return login_and_forward(request, user_) + else: + return HttpResponseRedirect(reverse('index')) else: provider_class = AUTH_PROVIDERS[request.session['auth_provider']].consumer user_data = provider_class.get_user_data(request.session['assoc_key']) @@ -156,6 +172,9 @@ def external_register(request): if not email: email = request.session.get('auth_email_request', '') + if email: + request.session['auth_validated_email'] = email + form1 = SimpleRegistrationForm(initial={ 'next': '/', 'username': username, @@ -173,6 +192,119 @@ def external_register(request): 'gravatar_faq_url':reverse('faq') + '#gravatar', }, context_instance=RequestContext(request)) +def request_temp_login(request): + if request.method == 'POST': + form = TemporaryLoginRequestForm(request.POST) + + if form.is_valid(): + user = form.user_cache + + try: + hash = get_object_or_404(ValidationHash, user=user, type='templogin') + if hash.expiration < datetime.datetime.now(): + hash.delete() + return request_temp_login(request) + except: + hash = ValidationHash.objects.create_new(user, 'templogin', [user.id]) + + send_email(_("Temporary login link"), [user.email], "auth/temp_login_email.html", { + 'temp_login_code': hash, + 'user': user + }) + + return HttpResponseRedirect(reverse('index')) + else: + form = TemporaryLoginRequestForm() + + return render_to_response( + 'auth/temp_login_request.html', {'form': form}, + context_instance=RequestContext(request)) + +def temp_signin(request, user, code): + user = get_object_or_404(User, id=user) + + if (ValidationHash.objects.validate(code, user, 'templogin', [user.id])): + print user.get_absolute_url() + return login_and_forward(request, user, reverse('user_authsettings'), + _("You are logged in with a temporary access key, please take the time to fix your issue with authentication.")) + else: + raise Http404() + +def send_validation_email(user): + hash = ValidationHash.objects.create_new(user, 'email', [user.email]) + send_email(_("Email Validation"), [user.email], "auth/email_validation.html", { + 'validation_code': hash, + 'user': user + }) + +def validate_email(request, user, code): + user = get_object_or_404(User, id=user) + + if (ValidationHash.objects.validate(code, user, 'email', [user.email])): + user.email_isvalid = True + user.save() + return login_and_forward(request, user, None, _("Thank you, your email is now validated.")) + else: + raise Http404() + +@login_required +def auth_settings(request): + """ + change password view. + + url : /changepw/ + template: authopenid/changepw.html + """ + user_ = request.user + auth_keys = user_.auth_keys.all() + + if user_.has_usable_password(): + FormClass = ChangePasswordForm + else: + FormClass = SetPasswordForm + + if request.POST: + form = FormClass(request.POST, user=user_) + if form.is_valid(): + if user_.has_usable_password(): + request.user.message_set.create(message=_("Your password was changed")) + else: + request.user.message_set.create(message=_("New password set")) + + user_.set_password(form.cleaned_data['password1']) + user_.save() + return HttpResponseRedirect(reverse('user_authsettings')) + else: + form = FormClass(user=user_) + + auth_keys_list = [] + + for k in auth_keys: + provider = AUTH_PROVIDERS.get(k.provider, None) + + if provider is not None: + name = "%s: %s" % (provider.context.human_name, provider.context.readable_key(k)) + else: + from forum.authentication.base import ConsumerTemplateContext + "unknown: %s" % ConsumerTemplateContext.readable_key(k) + + auth_keys_list.append({ + 'name': name, + 'id': k.id + }) + + return render_to_response('auth/auth_settings.html', { + 'form': form, + 'has_password': user_.has_usable_password(), + 'auth_keys': auth_keys_list, + }, context_instance=RequestContext(request)) + +def remove_external_provider(request, id): + association = get_object_or_404(AuthKeyUserAssociation, id=id) + request.user.message_set.create(message=_("You removed the association with %s") % association.provider) + association.delete() + return HttpResponseRedirect(reverse('user_authsettings')) + def newquestion_signin_action(user): question = Question.objects.filter(author=user).order_by('-added_at')[0] return question.get_absolute_url() @@ -186,7 +318,7 @@ POST_SIGNIN_ACTIONS = { 'newanswer': newanswer_signin_action, } -def login_and_forward(request, user): +def login_and_forward(request, user, forward=None, message=None): old_session = request.session.session_key user.backend = "django.contrib.auth.backends.ModelBackend" login(request, user) @@ -194,19 +326,24 @@ def login_and_forward(request, user): from forum.models import user_logged_in user_logged_in.send(user=user,session_key=old_session,sender=None) - signin_action = request.session.get('on_signin_action', None) - if not signin_action: - redirect = request.session.get('on_signin_url', None) + if not forward: + signin_action = request.session.get('on_signin_action', None) + if not signin_action: + forward = request.session.get('on_signin_url', None) - if not redirect: - redirect = reverse('index') - else: - try: - redirect = POST_SIGNIN_ACTIONS[signin_action](user) - except: - redirect = reverse('index') + if not forward: + forward = reverse('index') + else: + try: + forward = POST_SIGNIN_ACTIONS[signin_action](user) + except: + forward = reverse('index') + + if message is None: + message = _("Welcome back %s, you are now logged in") % user.username - return HttpResponseRedirect(redirect) + request.user.message_set.create(message=message) + return HttpResponseRedirect(forward) @login_required def signout(request): diff --git a/forum/views/users.py b/forum/views/users.py index baa8090b..ff92803c 100755 --- a/forum/views/users.py +++ b/forum/views/users.py @@ -947,44 +947,13 @@ USER_TEMPLATE_VIEWS = ( ) ) -def user(request, id): +def user(request, id, slug=None): sort = request.GET.get('sort', 'stats') user_view = dict((v.id, v) for v in USER_TEMPLATE_VIEWS).get(sort, USER_TEMPLATE_VIEWS[0]) from forum.views import users func = user_view.view_func return func(request, id, user_view) - -@login_required -def changepw(request): - """ - change password view. - - url : /changepw/ - template: authopenid/changepw.html - """ - logging.debug('') - user_ = request.user - - if not user_.has_usable_password(): - raise Http404 - - if request.POST: - form = ChangePasswordForm(request.POST, user=user_) - if form.is_valid(): - user_.set_password(form.cleaned_data['password1']) - user_.save() - msg = _("Password changed.") - redirect = "%s?msg=%s" % ( - reverse('user_account_settings'), - urlquote_plus(msg)) - return HttpResponseRedirect(redirect) - else: - form = ChangePasswordForm(user=user_) - - return render_to_response('changepw.html', {'form': form }, - context_instance=RequestContext(request)) - @login_required def account_settings(request): """ |