]> git.openstreetmap.org Git - osqa.git/commitdiff
Closes OSQA 175 and OSQA 318. Added a bunch of options to configure the email validat...
authorhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Thu, 24 Jun 2010 00:57:31 +0000 (00:57 +0000)
committerhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Thu, 24 Jun 2010 00:57:31 +0000 (00:57 +0000)
git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@443 0cfe37f9-358a-4d5e-be75-b63607b5c754

14 files changed:
forum/actions/user.py
forum/badges/base.py
forum/models/user.py
forum/settings/users.py
forum/skins/default/templates/ask.html
forum/skins/default/templates/auth/mail_validation.html [new file with mode: 0644]
forum/skins/default/templates/auth/welcome_email.html [moved from forum/skins/default/templates/auth/email_validation.html with 100% similarity]
forum/skins/default/templates/question.html
forum/skins/default/templates/users/info.html
forum/urls.py
forum/views/auth.py
forum/views/users.py
forum/views/writers.py
settings_local.py.dist

index e8f1035d3a2d0946651ecb37fb40caf2454f5d34..8f225d2f9cea65436b54f9b2a13e9171340772cb 100644 (file)
@@ -13,7 +13,7 @@ class UserJoinsAction(ActionProxy):
 
     def process_action(self):
         hash = ValidationHash.objects.create_new(self.user, 'email', [self.user.email])
-        send_template_email([self.user], "auth/email_validation.html", {'validation_code': hash})
+        send_template_email([self.user], "auth/welcome_email.html", {'validation_code': hash})
 
     def describe(self, viewer=None):
         return _("%(user)s %(have_has)s joined the %(app_name)s Q&A community") % {
index 1900119284224270ab6d954d7e6a680e6fd1b4dc..79fcb523c73d5b1d1ab7c9a25becedc5cac40ca0 100644 (file)
@@ -69,7 +69,7 @@ class AbstractBadge(object):
             trigger = isinstance(action, Action) and action or None
 
             if not awarded:
-                AwardAction(user=user, node=node, ip=action.ip).save(data=dict(badge=cls.ondb, trigger=trigger))
+                AwardAction(user=user, node=node).save(data=dict(badge=cls.ondb, trigger=trigger))
         except MultipleObjectsReturned:
             if node:
                 logging.error('Found multiple %s badges awarded for user %s (%s)' % (self.name, user.username, user.id))
index 89bea283824f67b75f7bb8d9a642b3769c14befd..f5eb9a615304bcd045617859fc01f8b0d6c6623e 100644 (file)
@@ -90,6 +90,16 @@ def true_if_is_super_or_staff(fn):
 
     return decorated
 
+def false_if_validation_required_to(item):
+    def decorator(fn):
+        def decorated(self, *args, **kwargs):
+            if item in settings.REQUIRE_EMAIL_VALIDATION_TO and not self.email_isvalid:
+                return False
+            else:
+                return fn(self, *args, **kwargs)
+        return decorated
+    return decorator
+
 class User(BaseModel, DjangoUser):
     is_approved = models.BooleanField(default=False)
     email_isvalid = models.BooleanField(default=False)
@@ -116,7 +126,7 @@ class User(BaseModel, DjangoUser):
 
     @property
     def is_siteowner(self):
-        #temporary thing, for now lets just assume that the site owner will always be the first user of the application
+        #todo: temporary thing, for now lets just assume that the site owner will always be the first user of the application
         return self.id == 1
 
     @property
@@ -191,6 +201,7 @@ class User(BaseModel, DjangoUser):
     def can_vote_down(self):
         return self.reputation >= int(settings.REP_TO_VOTE_DOWN)
 
+    @false_if_validation_required_to('flag')
     def can_flag_offensive(self, post=None):
         if post is not None and post.author == self:
             return False
@@ -203,9 +214,10 @@ class User(BaseModel, DjangoUser):
         return self.reputation >= int(settings.REP_TO_VIEW_FLAGS)
 
     @true_if_is_super_or_staff
+    @false_if_validation_required_to('comment')
     def can_comment(self, post):
         return self == post.author or self.reputation >= int(settings.REP_TO_COMMENT
-                                                             ) or (post.__class__.__name__ == "Answer" and self == post.question.author)
+                ) or (post.__class__.__name__ == "Answer" and self == post.question.author)
 
     @true_if_is_super_or_staff
     def can_like_comment(self, comment):
@@ -271,6 +283,12 @@ class User(BaseModel, DjangoUser):
     def can_upload_files(self):
         return self.reputation >= int(settings.REP_TO_UPLOAD)
 
+    def email_valid_and_can_ask(self):
+        return 'ask' not in settings.REQUIRE_EMAIL_VALIDATION_TO or self.email_isvalid
+
+    def email_valid_and_can_answer(self):
+        return 'answer' not in settings.REQUIRE_EMAIL_VALIDATION_TO or self.email_isvalid
+
     def check_password(self, old_passwd):
         self.__dict__.update(self.__class__.objects.filter(id=self.id).values('password')[0])
         return DjangoUser.check_password(self, old_passwd)
index 01377d7664fac9141047ad57aad89d571a8d23ac..07f47b6a7f6943f6c81c259ec45c610bd4710c0e 100644 (file)
@@ -1,4 +1,5 @@
 from forms import CommaStringListWidget
+from django.forms import CheckboxSelectMultiple
 from base import Setting, SettingSet
 from django.utils.translation import ugettext as _
 
@@ -24,3 +25,20 @@ EMAIL_UNIQUE = Setting('EMAIL_UNIQUE', True, USERS_SET, dict(
 label = _("Force unique email"),
 help_text = _("Should each user have an unique email.")))
 
+REQUIRE_EMAIL_VALIDATION_TO = Setting('REQUIRE_EMAIL_VALIDATION_TO', [], USERS_SET, dict(
+label = _("Require email validation to..."),
+help_text = _("Which actions in this site, users without a valid email will be prevented from doing."),
+widget=CheckboxSelectMultiple,
+choices=(("ask", _("ask questions")), ("answer", _("provide answers")), ("comment", _("make comments")), ("flag", _("report posts"))),
+required=False,
+))
+
+HOLD_PENDING_POSTS_MINUTES = Setting('HOLD_PENDING_POSTS_MINUTES', 120, USERS_SET, dict(
+label=_("Hold pending posts for X minutes"),
+help_text=_("How much time in minutes a post should be kept in session until the user logs in or validates the email.")
+))
+
+WARN_PENDING_POSTS_MINUTES = Setting('WARN_PENDING_POSTS_MINUTES', 15, USERS_SET, dict(
+label=_("Warn about pending posts afer X minutes"),
+help_text=_("How much time in minutes a user that just logged in or validated his email should be warned about a pending post instead of publishing it automatically.")
+))
\ No newline at end of file
index 4eb806b1feb2cf8c980f478814ccd95a97d39a6a..2f2b92e1463cf16dd56a835a3bdb6047d141cf64 100644 (file)
         <form id="fmask" action="" method="post" accept-charset="utf-8">
                        {% if not request.user.is_authenticated %}
             <div class="message">
-                           <p>{% trans "login to post question info" %}</p>
+                <span class="strong big">{% trans "You are welcome to start submitting your question anonymously." %}</span>
+                <p>{% blocktrans %}
+                    After submiting your question, you will be redirected to the login/signup page.
+                    Your question will be saved in the current session and will be published after you login with your existing account,
+                    or signup for a new account{% endblocktrans %}{% if "ask" in settings.REQUIRE_EMAIL_VALIDATION_TO %}
+                    {% trans "and validate your email." %}{% else %}.{% endif %}</p>
             </div>
             {% else %}
-                {% ifequal settings.EMAIL_VALIDATION 'on' %}
-                    {% if not request.user.email_isvalid %}
-                        <div class="message">
-                            {% blocktrans with request.user.email as email %}must have valid {{email}} to post, 
-                            see {{email_validation_faq_url}}
-                            {% endblocktrans %}
-                        </div>
-                    {% endif %}
-                {% endifequal %}
+                {% if not request.user.email_valid_and_can_ask %}
+                    <div class="message">
+                        {% blocktrans %}Remember, your question will not be published until you validate your email.{% endblocktrans %}
+                        <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+                    </div>
+                {% endif %}
                        {% endif %}
             <div class="form-item">
                 <label for="id_title" ><strong>{{ form.title.label_tag }}:</strong></label> <span class="form-error"></span><br/>
diff --git a/forum/skins/default/templates/auth/mail_validation.html b/forum/skins/default/templates/auth/mail_validation.html
new file mode 100644 (file)
index 0000000..d73a428
--- /dev/null
@@ -0,0 +1,30 @@
+{% load i18n extra_tags email_tags %}
+
+{% declare %}
+    prefix = settings.EMAIL_SUBJECT_PREFIX
+    app_name = settings.APP_SHORT_NAME
+
+    exclude_finetune = True
+{% enddeclare %}
+
+{% email %}
+    {% subject %}{% blocktrans %}{{ prefix }} Your email validation link {{ app_name }}{% endblocktrans %}{% endsubject %}
+
+    {% htmlcontent notifications/base.html %}
+        <p style="{{ p_style }}}">{% trans "Please use the following link to help us verify your email address:" %}</p>
+
+        <a  style="{{ a_style }}}" href="{% fullurl auth_validate_email user=recipient.id,code=validation_code %}">{% trans "Validate my email address" %}</a>
+
+        <p style="{{ p_style }}}">{% trans "If the above link is not clickable, copy and paste this url into your web browser's address bar:" %}</p>
+
+        <p style="{{ p_style }}">{% fullurl auth_validate_email user=recipient.id,code=validation_code %}</p>
+    {% endhtmlcontent %}
+
+{% textcontent notifications/base_text.html %}
+{% trans "Copy and paste this url into your web browser's address bar to help us verify your email address:" %}
+
+{% fullurl auth_validate_email user=recipient.id,code=validation_code %}
+{% endtextcontent %}
+
+{% endemail %}
+
index 81711e02f34d50332ad1ebeaaa4d70e159a12a60..694ab715d2740ecfabd5d323d2f1ffb2b52be61b 100644 (file)
                     {% endspaceless %}\r
                 </div>\r
                 {% if not request.user.is_authenticated %}\r
-                    <div class="message">{% trans "you can answer anonymously and then login" %}</div>\r
+                    <div class="message">{% trans "You can answer anonymously and then login." %}</div>\r
                 {% else %}\r
                     <p class="message">\r
                         {% ifequal request.user question.author  %}\r
-                            {% trans "answer your own question only to give an answer" %}\r
+                            {% trans "Answer your own question only to give an answer." %}\r
                         {% else %}\r
-                            {% trans "please only give an answer, no discussions" %}\r
+                            {% trans "Please only give an answer, no discussions." %}\r
                         {% endifequal %}\r
+                        {% if not request.user.email_valid_and_can_answer %}\r
+                            {% blocktrans %}Remember, your answer will not be published until you validate your email.{% endblocktrans %}\r
+                            <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>\r
+                        {% endif %}\r
                     </p>\r
                 {% endif %}\r
 \r
index b533f00d605808b7e55b33db641e28a8630f8646..8ffc7fa5cb385066cfaadcac3c100fbabad76c4c 100644 (file)
                     {% endif %}
                 </tr>
                 {% endif %}
-                {% if request.user.is_superuser %}
+                {% if can_view_private %}
                 <tr>
                     <td>{% trans "email" %}</td>
-                    <td><a href="mailto: {{ view_user.email }}">{{ view_user.email }}</a></td>
+                    <td>
+                        <a href="mailto: {{ view_user.email }}">{{ view_user.email }}</a>
+                        {% if not view_user.email_isvalid %}
+                            ({% trans "not validated" %})
+                            {% ifequal request.user view_user %}
+                                </td></tr><tr><td></td><td><a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+                            {% endifequal %}
+                        {% endif %}
+                    </td>
                 </tr>
                 {% endif %}
                                <!--
index 6bb315dbdc2b927e550788416725275e7136ba4b..1d8b213e5b2f5d77ba134f3bb8170c05be71274a 100644 (file)
@@ -69,7 +69,8 @@ urlpatterns += patterns('',
                             kwargs=dict(close=True), name='close'),
                         url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')), app.commands.close,
                             kwargs=dict(close=False), name='reopen'),
-                        url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')), app.writers.answer, name='answer'),
+                        url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')), app.writers.answer, name='answer'),                        
+                        url(r'^%s(?P<action>\w+)/$' % _('pending-data/'), app.writers.manage_pending_data, name='manage_pending_data'),
 
                         url(r'^%s(?P<id>\d+)/(?P<vote_type>[a-z]+)/' % _('vote/'), app.commands.vote_post,
                             name='vote_post'),
@@ -144,8 +145,6 @@ urlpatterns += patterns('',
 
                         url(r'^%s%s$' % (_('account/'), _('signin/')), app.auth.signin_page, name='auth_signin'),
                         url(r'^%s%s$' % (_('account/'), _('signout/')), app.auth.signout, name='user_signout'),
-                        url(r'^%s%s(?P<action>\w+)/$' % (_('account/'), _('signin/')), app.auth.signin_page,
-                            name='auth_action_signin'),
                         url(r'^%s(?P<provider>\w+)/%s$' % (_('account/'), _('signin/')),
                             app.auth.prepare_provider_signin, name='auth_provider_signin'),
                         url(r'^%s(?P<provider>\w+)/%s$' % (_('account/'), _('done/')), app.auth.process_provider_signin,
@@ -164,6 +163,7 @@ urlpatterns += patterns('',
                             app.auth.remove_external_provider, name='user_remove_external_provider'),
                         url(r'^%s%s%s$' % (_('account/'), _('providers/'), _('add/')), app.auth.signin_page,
                             name='user_add_external_provider'),
+                        url(r'^%s%s$' %(_('account/'), _('send-validation/')), app.auth.send_validation_email, name="send_validation_email"),
 
 
                         url(r'^%s$' % _('admin/'), app.admin.dashboard, name="admin_index"),
index 7f9b91e6e0b33c4a9000b41b042223596467357b..90af33b20013f18785f7dafb228a5797dda7a5a6 100644 (file)
@@ -11,6 +11,9 @@ from django.contrib.auth.decorators import login_required
 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
@@ -25,12 +28,8 @@ from forum.authentication import AUTH_PROVIDERS
 from forum.models import AuthKeyUserAssociation, ValidationHash, Question, Answer
 from forum.actions import UserJoinsAction
 
-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})
+def signin_page(request):
+    request.session['on_signin_url'] = request.META.get('HTTP_REFERER', '/')
 
     all_providers = [provider.context for provider in AUTH_PROVIDERS.values()]
 
@@ -263,6 +262,24 @@ def temp_signin(request, user, code):
     else:
         raise Http404()
 
+def send_validation_email(request):
+    if not request.user.is_authenticated():
+        return HttpResponseUnauthorized(request)
+    else:
+        try:
+            hash = ValidationHash.objects.get(user=request.user, type='email')
+            if hash.expiration < datetime.datetime.now():
+                hash.delete()
+                return send_validation_email(request)
+        except:
+            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)
 
@@ -338,19 +355,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 +362,27 @@ 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 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'))
-
-    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')
-        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
 
     request.user.message_set.create(message=message)
+
+    forward = request.session.get('on_signin_url', reverse('index'))
+    pending_data = request.session.get('pending_submission_data', 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_data']
+        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:
+            return manage_pending_data(request, _('save'), forward)
+
     return HttpResponseRedirect(forward)
 
 def forward_suspended_user(request, user, show_private_msg=True):
index 6cc079bd14205a2e688c2473ec04b2f38a2c3eef..dee69cd839a458fe37d9c86f7e61177b230fcebf 100644 (file)
@@ -75,13 +75,6 @@ def users(request):
         }\r
     }\r
 \r
-def set_new_email(user, new_email, nomessage=False):\r
-    if new_email != user.email:\r
-        user.email = new_email\r
-        user.email_isvalid = False\r
-        user.save()\r
-    #if settings.EMAIL_VALIDATION == 'on':\r
-    #    send_new_email_key(user,nomessage=nomessage)\r
 \r
 @login_required\r
 def edit_user(request, id):\r
@@ -93,7 +86,9 @@ def edit_user(request, id):
         if form.is_valid():\r
             new_email = sanitize_html(form.cleaned_data['email'])\r
 \r
-            set_new_email(user, new_email)\r
+            if new_email != user.email:\r
+                user.email = new_email\r
+                user.email_isvalid = False\r
 \r
             if settings.EDITABLE_SCREEN_NAME:\r
                 user.username = sanitize_html(form.cleaned_data['username'])\r
@@ -108,6 +103,7 @@ def edit_user(request, id):
             user.save()\r
             EditProfileAction(user=user, ip=request.META['REMOTE_ADDR']).save()\r
 \r
+            request.user.message_set.create(message=_("Profile updated."))\r
             return HttpResponseRedirect(user.get_profile_url())\r
     else:\r
         form = EditUserForm(user)\r
index e6309c80217380ee51863a7dd657292b6ac4c56f..7dc2e33ac50866274ce2c249c0ce2336ce25bf05 100644 (file)
@@ -17,6 +17,7 @@ from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction,
 from forum.forms import *
 from forum.models import *
 from forum.forms import get_next_url
+from forum.utils import html
 
 
 def upload(request):#ajax upload file to a question or answer
@@ -64,24 +65,42 @@ def upload(request):#ajax upload file to a question or answer
     return HttpResponse(result, mimetype="application/xml")
 
 def ask(request):
-    if request.POST and "text" in request.POST:
-        form = AskForm(request.POST, user=request.user)
-        if form.is_valid():
-            if request.user.is_authenticated():
-                ask_action = AskAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
-                question = ask_action.node
+    form = None
 
-                if settings.WIKI_ON and request.POST.get('wiki', False):
-                    question.nstate.wiki = ask_action
-
-                return HttpResponseRedirect(question.get_absolute_url())
-            else:
-                request.session['temp_node_data'] = request.POST
-                request.session['temp_node_type'] = 'question'
-                return HttpResponseRedirect(reverse('auth_action_signin', kwargs={'action': 'newquestion'}))
-    elif request.method == "POST" and "go" in request.POST:
-        form = AskForm({'title': request.POST['q']}, user=request.user)
-    else:
+    if request.POST:
+        if request.session.pop('reviewing_pending_data', False):
+            form = AskForm(initial=request.POST, user=request.user)
+        elif "text" in request.POST:
+            form = AskForm(request.POST, user=request.user)
+            if form.is_valid():
+                if request.user.is_authenticated() and request.user.email_valid_and_can_ask():
+                    ask_action = AskAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
+                    question = ask_action.node
+
+                    if settings.WIKI_ON and request.POST.get('wiki', False):
+                        question.nstate.wiki = ask_action
+
+                    return HttpResponseRedirect(question.get_absolute_url())
+                else:
+                    request.session['pending_submission_data'] = {
+                        'POST': request.POST,
+                        'data_name': _("question"),
+                        'type': 'ask',
+                        'submission_url': reverse('ask'),
+                        'time': datetime.datetime.now()
+                    }
+
+                    if request.user.is_authenticated():
+                        request.user.message_set.create(message=_("Your question is pending until you %s.") % html.hyperlink(
+                            reverse('send_validation_email'), _("validate your email")
+                        ))
+                        return HttpResponseRedirect(reverse('index'))
+                    else:
+                        return HttpResponseRedirect(reverse('auth_signin'))
+        elif "go" in request.POST:
+            form = AskForm({'title': request.POST['q']}, user=request.user)
+            
+    if not form:
         form = AskForm(user=request.user)
 
     return render_to_response('ask.html', {
@@ -197,25 +216,55 @@ def edit_answer(request, id):
 
 def answer(request, id):
     question = get_object_or_404(Question, id=id)
+
     if request.POST:
         form = AnswerForm(question, request.POST)
-        if form.is_valid():
-            if request.user.is_authenticated():
-                answer_action = AnswerAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(dict(question=question, **form.cleaned_data))
-                answer = answer_action.node
 
-                if settings.WIKI_ON and request.POST.get('wiki', False):
-                    answer.nstate.wiki = answer_action
-
-                return HttpResponseRedirect(answer.get_absolute_url())
-            else:
-                request.session['temp_node_data'] = request.POST
-                request.session['temp_node_type'] = 'answer'
-                request.session['temp_question_id'] = id
-                return HttpResponseRedirect(reverse('auth_action_signin', kwargs={'action': 'newquestion'}))
-        else:
+        if request.session.pop('reviewing_pending_data', False) or not form.is_valid():
             request.session['redirect_POST_data'] = request.POST
             return HttpResponseRedirect(question.get_absolute_url() + '#fmanswer')
 
+        if request.user.is_authenticated() and request.user.email_valid_and_can_answer():
+            answer_action = AnswerAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(dict(question=question, **form.cleaned_data))
+            answer = answer_action.node
+
+            if settings.WIKI_ON and request.POST.get('wiki', False):
+                answer.nstate.wiki = answer_action
+
+            return HttpResponseRedirect(answer.get_absolute_url())
+        else:
+            request.session['pending_submission_data'] = {
+                'POST': request.POST,
+                'data_name': _("answer"),
+                'type': 'answer',
+                'submission_url': reverse('answer', kwargs={'id': id}),
+                'time': datetime.datetime.now()
+            }
+
+            if request.user.is_authenticated():
+                request.user.message_set.create(message=_("Your answer is pending until you %s.") % html.hyperlink(
+                    reverse('send_validation_email'), _("validate your email")
+                ))
+                return HttpResponseRedirect(question.get_absolute_url())
+            else:
+                return HttpResponseRedirect(reverse('auth_signin'))
+
     return HttpResponseRedirect(question.get_absolute_url())
 
+
+def manage_pending_data(request, action, forward=None):
+    pending_data = request.session.pop('pending_submission_data', None)
+
+    if not pending_data:
+        raise Http404
+
+    if action == _("cancel"):
+        return HttpResponseRedirect(forward or request.META.get('HTTP_REFERER', '/'))
+    else:
+        if action == _("review"):
+            request.session['reviewing_pending_data'] = True
+
+        request.session['redirect_POST_data'] = pending_data['POST']
+        return HttpResponseRedirect(pending_data['submission_url'])
+
+
index 6d0e446708d017463d735cd9a2835da739d01745..8f997e5253a1c2082b6790ec867d87f936fcf8ef 100644 (file)
@@ -54,8 +54,6 @@ FORUM_SCRIPT_ALIAS = '' #no leading slash, default = '' empty string
 USE_I18N = True
 LANGUAGE_CODE = 'en'
 
-EMAIL_VALIDATION = 'off' #string - on|off
-
 DJANGO_VERSION = 1.1
 OSQA_DEFAULT_SKIN = 'default'