X-Git-Url: https://git.openstreetmap.org./osqa.git/blobdiff_plain/25d2724e64a7828113860d6f7232815a34133ec1..745f67c37acdb9574c5297004adde2b9a7da5fdb:/forum/views/auth.py diff --git a/forum/views/auth.py b/forum/views/auth.py index 7f9b91e..f17d6d2 100644 --- a/forum/views/auth.py +++ b/forum/views/auth.py @@ -7,32 +7,42 @@ from forum.http_responses import HttpResponseUnauthorized 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 forum.views.decorators import login_required +from forum.modules import decorate from django.contrib.auth import login, logout from django.http import get_host from forum.actions import SuspendAction +from forum.utils import html +from forum import settings +from writers import manage_pending_data import types import datetime import logging from forum.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm, \ TemporaryLoginRequestForm, ChangePasswordForm, SetPasswordForm -from forum.utils.mail import send_email, send_template_email +from forum.utils.mail import send_template_email from forum.authentication.base import InvalidAuthentication from forum.authentication import AUTH_PROVIDERS from forum.models import AuthKeyUserAssociation, ValidationHash, Question, Answer -from forum.actions import UserJoinsAction +from forum.actions import UserJoinsAction, EmailValidationAction +from forum.models.action import ActionRepute -def signin_page(request, action=None): - if action is None: - request.session['on_signin_url'] = request.META.get('HTTP_REFERER', '/') - else: - request.session['on_signin_action'] = action - request.session['on_signin_url'] = reverse('auth_action_signin', kwargs={'action': action}) - all_providers = [provider.context for provider in AUTH_PROVIDERS.values()] +from forum.settings import REP_GAIN_BY_EMAIL_VALIDATION +from vars import ON_SIGNIN_SESSION_ATTR, PENDING_SUBMISSION_SESSION_ATTR + +def signin_page(request): + referer = request.META.get('HTTP_REFERER', '/') + + # If the referer is equal to the sign up page, e. g. if the previous login attempt was not successful we do not + # change the sign in URL. The user should go to the same page. + if not referer.replace(settings.APP_URL, '') == reverse('auth_signin'): + request.session[ON_SIGNIN_SESSION_ATTR] = referer + + all_providers = [provider.context for provider in AUTH_PROVIDERS.values() if provider.context] sort = lambda c1, c2: c1.weight - c2.weight can_show = lambda c: not request.user.is_authenticated() or c.show_to_logged_in_user @@ -138,7 +148,7 @@ def process_provider_signin(request, provider): assoc = AuthKeyUserAssociation.objects.get(key=assoc_key) user_ = assoc.user return login_and_forward(request, user_) - except: + except AuthKeyUserAssociation.DoesNotExist: request.session['assoc_key'] = assoc_key request.session['auth_provider'] = provider return HttpResponseRedirect(reverse('auth_external_register')) @@ -217,7 +227,7 @@ def external_register(request): return render_to_response('auth/complete.html', { 'form1': form1, 'email_feeds_form': email_feeds_form, - 'provider':mark_safe(provider_context.human_name), + 'provider':provider_context and mark_safe(provider_context.human_name) or _('unknown'), 'login_type':provider_context.id, 'gravatar_faq_url':reverse('faq') + '#gravatar', }, context_instance=RequestContext(request)) @@ -227,22 +237,24 @@ def request_temp_login(request): form = TemporaryLoginRequestForm(request.POST) if form.is_valid(): - user = form.user_cache + users = form.user_cache - if user.is_suspended(): - return forward_suspended_user(request, user, False) + for u in users: + if u.is_suspended(): + return forward_suspended_user(request, u, False) - 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]) + for u in users: + try: + hash = get_object_or_404(ValidationHash, user=u, type='templogin') + if hash.expiration < datetime.datetime.now(): + hash.delete() + return request_temp_login(request) + except: + hash = ValidationHash.objects.create_new(u, 'templogin', [u.id]) - send_template_email([user], "auth/temp_login_email.html", {'temp_login_code': hash}) + send_template_email([u], "auth/temp_login_email.html", {'temp_login_code': hash}) - request.user.message_set.create(message=_("An email has been sent with your temporary login key")) + request.user.message_set.create(message=_("An email has been sent with your temporary login key")) return HttpResponseRedirect(reverse('index')) else: @@ -256,6 +268,11 @@ def temp_signin(request, user, code): user = get_object_or_404(User, id=user) if (ValidationHash.objects.validate(code, user, 'templogin', [user.id])): + + # If the user requests temp_signin he must have forgotten his password. So we mark it as unusable. + user.set_unusable_password() + user.save() + return login_and_forward(request, user, reverse('user_authsettings', kwargs={'id': user.id}), _( "You are logged in with a temporary access key, please take the time to fix your issue with authentication." @@ -263,17 +280,41 @@ def temp_signin(request, user, code): else: raise Http404() +def send_validation_email(request): + if not request.user.is_authenticated(): + return HttpResponseUnauthorized(request) + else: + # We check if there are some old validation hashes. If there are -- we delete them. + try: + hash = ValidationHash.objects.get(user=request.user, type='email') + hash.delete() + except: + pass + + # We don't care if there are previous cashes in the database... In every case we have to create a new one + hash = ValidationHash.objects.create_new(request.user, 'email', [request.user.email]) + + send_template_email([request.user], "auth/mail_validation.html", {'validation_code': hash}) + request.user.message_set.create(message=_("A message with an email validation link was just sent to your address.")) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + + + 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.")) + EmailValidationAction(user=user, ip=request.META['REMOTE_ADDR']).save() + if REP_GAIN_BY_EMAIL_VALIDATION > 0: + message = _("Thank you, your email is now validated and you've got %d points." % int(REP_GAIN_BY_EMAIL_VALIDATION)) + + else: + message = _("Thank you, your email is now validated.") + + return login_and_forward(request, user, reverse('index'), message) else: - raise Http404() + return render_to_response('auth/mail_already_validated.html', { 'user' : user }, RequestContext(request)) -@login_required def auth_settings(request, id): user_ = get_object_or_404(User, id=id) @@ -327,6 +368,7 @@ def auth_settings(request, id): 'form': form, 'has_password': user_.has_usable_password(), 'auth_keys': auth_keys_list, + 'allow_local_auth': AUTH_PROVIDERS.get('local', None), }, context_instance=RequestContext(request)) def remove_external_provider(request, id): @@ -338,19 +380,6 @@ def remove_external_provider(request, id): association.delete() return HttpResponseRedirect(reverse('user_authsettings', kwargs={'id': association.user.id})) -def newquestion_signin_action(user): - question = Question.objects.filter(author=user).order_by('-added_at')[0] - return question.get_absolute_url() - -def newanswer_signin_action(user): - answer = Answer.objects.filter(author=user).order_by('-added_at')[0] - return answer.get_absolute_url() - -POST_SIGNIN_ACTIONS = { -'newquestion': newquestion_signin_action, -'newanswer': newanswer_signin_action, -} - def login_and_forward(request, user, forward=None, message=None): if user.is_suspended(): return forward_suspended_user(request, user) @@ -358,35 +387,29 @@ def login_and_forward(request, user, forward=None, message=None): user.backend = "django.contrib.auth.backends.ModelBackend" login(request, user) - temp_data = request.session.pop('temp_node_data', None) - if temp_data: - request.POST = temp_data - node_type = request.session.pop('temp_node_type') + if message is None: + message = _("Welcome back %s, you are now logged in") % user.username - if node_type == "question": - from forum.views.writers import ask - return ask(request) - elif node_type == "answer": - from forum.views.writers import answer - return answer(request, request.session.pop('temp_question_id')) + request.user.message_set.create(message=message) 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 forward: - forward = reverse('index') + forward = request.session.get(ON_SIGNIN_SESSION_ATTR, reverse('index')) + + pending_data = request.session.get(PENDING_SUBMISSION_SESSION_ATTR, None) + + if pending_data and (user.email_isvalid or pending_data['type'] not in settings.REQUIRE_EMAIL_VALIDATION_TO): + submission_time = pending_data['time'] + if submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.HOLD_PENDING_POSTS_MINUTES)): + del request.session[PENDING_SUBMISSION_SESSION_ATTR] + elif submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.WARN_PENDING_POSTS_MINUTES)): + user.message_set.create(message=(_("You have a %s pending submission.") % pending_data['data_name']) + " %s, %s, %s" % ( + html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('save')}), _("save it")), + html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('review')}), _("review")), + html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('cancel')}), _("cancel")) + )) else: - try: - forward = POST_SIGNIN_ACTIONS[signin_action](user) - except: - forward = reverse('index') + return manage_pending_data(request, _('save'), forward) - if message is None: - message = _("Welcome back %s, you are now logged in") % user.username - - request.user.message_set.create(message=message) return HttpResponseRedirect(forward) def forward_suspended_user(request, user, show_private_msg=True): @@ -403,7 +426,7 @@ def forward_suspended_user(request, user, show_private_msg=True): request.user.message_set.create(message) return HttpResponseRedirect(reverse('index')) -@login_required +@decorate.withfn(login_required) def signout(request): logout(request) - return HttpResponseRedirect(reverse('index')) \ No newline at end of file + return HttpResponseRedirect(reverse('index'))