diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2014-05-28 14:52:10 -0300 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2014-05-28 14:52:10 -0300 |
commit | 1f96403bf11a2dd7405fc905afd7d906380b4dba (patch) | |
tree | 2e69a9a305aedfc9d3c0a3f36752dbf65aaaecd7 | |
parent | 7335046b4d311d709cdf10633c4a3f8551a468b7 (diff) | |
download | askbot-1f96403bf11a2dd7405fc905afd7d906380b4dba.tar.gz askbot-1f96403bf11a2dd7405fc905afd7d906380b4dba.tar.bz2 askbot-1f96403bf11a2dd7405fc905afd7d906380b4dba.zip |
added recaptcha on posts + first pass on watched user status
-rw-r--r-- | askbot/conf/minimum_reputation.py | 10 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/forms.py | 13 | ||||
-rw-r--r-- | askbot/forms.py | 55 | ||||
-rw-r--r-- | askbot/importers/stackexchange/management/commands/load_stackexchange.py | 2 | ||||
-rw-r--r-- | askbot/management/commands/add_admin.py | 3 | ||||
-rw-r--r-- | askbot/management/commands/createsuperuser.py | 3 | ||||
-rw-r--r-- | askbot/management/commands/remove_admin.py | 3 | ||||
-rw-r--r-- | askbot/management/commands/send_email_alerts.py | 2 | ||||
-rw-r--r-- | askbot/models/__init__.py | 18 | ||||
-rw-r--r-- | askbot/models/signals.py | 1 | ||||
-rw-r--r-- | askbot/templates/answer_edit.html | 4 | ||||
-rw-r--r-- | askbot/templates/authopenid/complete.html | 7 | ||||
-rw-r--r-- | askbot/templates/authopenid/signup_with_password.html | 5 | ||||
-rw-r--r-- | askbot/templates/feedback.html | 7 | ||||
-rw-r--r-- | askbot/templates/macros.html | 7 | ||||
-rw-r--r-- | askbot/templates/question/new_answer_form.html | 4 | ||||
-rw-r--r-- | askbot/templates/question_edit.html | 4 | ||||
-rw-r--r-- | askbot/templates/widgets/ask_form.html | 4 | ||||
-rw-r--r-- | askbot/views/meta.py | 6 |
19 files changed, 100 insertions, 58 deletions
diff --git a/askbot/conf/minimum_reputation.py b/askbot/conf/minimum_reputation.py index 58b41c18..d0db5891 100644 --- a/askbot/conf/minimum_reputation.py +++ b/askbot/conf/minimum_reputation.py @@ -17,6 +17,16 @@ MIN_REP = livesettings.ConfigurationGroup( settings.register( livesettings.IntegerValue( MIN_REP, + 'MIN_REP_TO_AUTOAPPROVE_USER', + default=10, + description=_('Become approved'), + help_text=_('Approved users bypass moderation and skip recaptcha') + ) +) + +settings.register( + livesettings.IntegerValue( + MIN_REP, 'MIN_REP_TO_VOTE_UP', default=5, description=_('Upvote') diff --git a/askbot/deps/django_authopenid/forms.py b/askbot/deps/django_authopenid/forms.py index 63d0ba13..9e069ed8 100644 --- a/askbot/deps/django_authopenid/forms.py +++ b/askbot/deps/django_authopenid/forms.py @@ -39,7 +39,7 @@ from django.conf import settings as django_settings from askbot.conf import settings as askbot_settings from askbot import const as askbot_const from django.utils.safestring import mark_safe -from recaptcha_works.fields import RecaptchaField +from askbot.forms import AskbotRecaptchaField from askbot.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm from askbot.utils.loading import load_module @@ -55,7 +55,6 @@ __all__ = [ 'OpenidSigninForm','OpenidRegisterForm', 'ClassicRegisterForm', 'ChangePasswordForm', 'ChangeEmailForm', 'EmailPasswordForm', 'DeleteForm', - 'ChangeOpenidForm' ] class LoginProviderField(forms.CharField): @@ -327,10 +326,7 @@ class SafeOpenidRegisterForm(OpenidRegisterForm): """ def __init__(self, *args, **kwargs): super(SafeOpenidRegisterForm, self).__init__(*args, **kwargs) - self.fields['recaptcha'] = RecaptchaField( - private_key = askbot_settings.RECAPTCHA_SECRET, - public_key = askbot_settings.RECAPTCHA_KEY - ) + self.fields['recaptcha'] = AskbotRecaptchaField() class ClassicRegisterForm(SetPasswordForm): """ legacy registration form """ @@ -347,10 +343,7 @@ class SafeClassicRegisterForm(ClassicRegisterForm): """ def __init__(self, *args, **kwargs): super(SafeClassicRegisterForm, self).__init__(*args, **kwargs) - self.fields['recaptcha'] = RecaptchaField( - private_key = askbot_settings.RECAPTCHA_SECRET, - public_key = askbot_settings.RECAPTCHA_KEY - ) + self.fields['recaptcha'] = AskbotRecaptchaField() class ChangePasswordForm(forms.Form): """ change password form """ diff --git a/askbot/forms.py b/askbot/forms.py index e4e927eb..550f6f14 100644 --- a/askbot/forms.py +++ b/askbot/forms.py @@ -24,6 +24,10 @@ from askbot.conf import get_tag_display_filter_strategy_choices from tinymce.widgets import TinyMCE import logging +def should_use_recaptcha(user): + """True if user must use recaptcha""" + return askbot_settings.USE_RECAPTCHA and (user.is_anonymous() or user.is_watched()) + def cleanup_dict(dictionary, key, empty_value): """deletes key from dictionary if it exists @@ -210,6 +214,14 @@ class CountedWordsField(forms.CharField): return value +class AskbotRecaptchaField(RecaptchaField): + """A recaptcha field with preset keys from the livesettings""" + def __init__(self, *args, **kwargs): + kwargs.setdefault('private_key', askbot_settings.RECAPTCHA_SECRET) + kwargs.setdefault('public_key', askbot_settings.RECAPTCHA_KEY) + super(AskbotRecaptchaField, self).__init__(*args, **kwargs) + + class LanguageField(forms.ChoiceField): def __init__(self, *args, **kwargs): @@ -721,13 +733,6 @@ class SendMessageForm(forms.Form): ) -class NotARobotForm(forms.Form): - recaptcha = RecaptchaField( - private_key=askbot_settings.RECAPTCHA_SECRET, - public_key=askbot_settings.RECAPTCHA_KEY - ) - - class FeedbackForm(forms.Form): name = forms.CharField(label=_('Your name (optional):'), required=False) email = forms.EmailField(label=_('Email:'), required=False) @@ -741,18 +746,12 @@ class FeedbackForm(forms.Form): ) next = NextUrlField() - def __init__(self, is_auth=False, *args, **kwargs): + def __init__(self, user=False, *args, **kwargs): super(FeedbackForm, self).__init__(*args, **kwargs) - self.is_auth = is_auth - if not is_auth: - if askbot_settings.USE_RECAPTCHA: - self._add_recaptcha_field() - - def _add_recaptcha_field(self): - self.fields['recaptcha'] = RecaptchaField( - private_key=askbot_settings.RECAPTCHA_SECRET, - public_key=askbot_settings.RECAPTCHA_KEY - ) + self.user = user.is_authenticated() + if should_use_recaptcha(user): + self.fields['recaptcha'] = AskbotRecaptchaField() + def clean_message(self): message = self.cleaned_data.get('message', '').strip() if not message: @@ -761,7 +760,7 @@ class FeedbackForm(forms.Form): def clean(self): super(FeedbackForm, self).clean() - if not self.is_auth: + if self.user.is_anonymous(): if not self.cleaned_data['no_email'] \ and not self.cleaned_data['email']: msg = _('Please mark "I dont want to give my mail" field.') @@ -942,6 +941,9 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm): if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False: self.hide_field('ask_anonymously') + if should_use_recaptcha(user): + self.fields['recaptcha'] = AskbotRecaptchaField() + def clean_ask_anonymously(self): """returns false if anonymous asking is not allowed """ @@ -978,6 +980,9 @@ class AskWidgetForm(forms.Form, FormWithHideableFields): self.fields['text'].required = False self.fields['text'].min_length = 0 + if should_use_recaptcha(user): + self.fields['recaptcha'] = AskbotRecaptchaField() + class CreateAskWidgetForm(forms.Form, FormWithHideableFields): title = forms.CharField(max_length=100) include_text_field = forms.BooleanField(required=False) @@ -1121,7 +1126,11 @@ class AnswerForm(PostAsSomeoneForm, PostPrivatelyForm): def __init__(self, *args, **kwargs): super(AnswerForm, self).__init__(*args, **kwargs) - self.fields['text'] = AnswerEditorField(user=kwargs['user']) + user = kwargs['user'] + self.fields['text'] = AnswerEditorField(user=user) + + if should_use_recaptcha(user): + self.fields['recaptcha'] = AskbotRecaptchaField() def has_data(self): """True if form is bound or has inital data""" @@ -1237,6 +1246,9 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm): if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False): self.fields['language'] = LanguageField() + if should_use_recaptcha(self.user): + self.fields['recaptcha'] = AskbotRecaptchaField() + def has_changed(self): if super(EditQuestionForm, self).has_changed(): return True @@ -1344,6 +1356,9 @@ class EditAnswerForm(PostAsSomeoneForm, PostPrivatelyForm): self.fields['text'].initial = revision.text self.fields['wiki'].initial = answer.wiki + if should_use_recaptcha(user): + self.fields['recaptcha'] = AskbotRecaptchaField() + def has_changed(self): #todo: this function is almost copy/paste of EditQuestionForm.has_changed() if super(EditAnswerForm, self).has_changed(): diff --git a/askbot/importers/stackexchange/management/commands/load_stackexchange.py b/askbot/importers/stackexchange/management/commands/load_stackexchange.py index ff6ddb15..902bc988 100644 --- a/askbot/importers/stackexchange/management/commands/load_stackexchange.py +++ b/askbot/importers/stackexchange/management/commands/load_stackexchange.py @@ -915,7 +915,7 @@ it may be helpful to split this procedure in two:\n u = askbot.User() u_type = se_u.user_type.name if u_type == 'Administrator': - u.set_admin_status() + u.set_status('d') elif u_type == 'Moderator': u.set_status('m') elif u_type not in ('Unregistered', 'Registered'): diff --git a/askbot/management/commands/add_admin.py b/askbot/management/commands/add_admin.py index 6f7c7034..3f8f7fea 100644 --- a/askbot/management/commands/add_admin.py +++ b/askbot/management/commands/add_admin.py @@ -41,5 +41,4 @@ class Command(NoArgsCommand): self.confirm_action() self.remove_signals() - self.user.set_admin_status() - self.user.save() + self.user.set_status('d') diff --git a/askbot/management/commands/createsuperuser.py b/askbot/management/commands/createsuperuser.py index eb363bbd..d0faf253 100644 --- a/askbot/management/commands/createsuperuser.py +++ b/askbot/management/commands/createsuperuser.py @@ -100,8 +100,7 @@ class Command(Command): self.remove_signals() u = User.objects.create_superuser(username, email, password) - u.set_admin_status() - u.save() + u.set_status('d') if verbosity >= 1: self.stdout.write("Askbot Superuser created successfully.\n") diff --git a/askbot/management/commands/remove_admin.py b/askbot/management/commands/remove_admin.py index 2aa95c20..eca0b7b6 100644 --- a/askbot/management/commands/remove_admin.py +++ b/askbot/management/commands/remove_admin.py @@ -41,5 +41,4 @@ class Command(NoArgsCommand): self.confirm_action() self.remove_signals() - self.user.remove_admin_status() - self.user.save() + self.user.set_status('a') diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py index dbaff93f..1f04690f 100644 --- a/askbot/management/commands/send_email_alerts.py +++ b/askbot/management/commands/send_email_alerts.py @@ -480,7 +480,7 @@ class Command(NoArgsCommand): 'name': user.username, 'admin_email': askbot_settings.ADMIN_EMAIL, 'site_name': askbot_settings.APP_SHORT_NAME, - 'is_multilingual': django_settings.ASKBOT_MULTILINGUAL + 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False) }) if DEBUG_THIS_COMMAND == True: diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 5dace35c..c6a9146a 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -99,8 +99,7 @@ def get_admin(): if User.objects.filter(username='_admin_').count() == 0: admin = User.objects.create_user('_admin_', '') admin.set_unusable_password() - admin.set_admin_status() - admin.save() + admin.set_status('d') return admin else: raise User.DoesNotExist @@ -2745,11 +2744,13 @@ def user_update_response_counts(user): def user_receive_reputation(self, num_points): - new_points = self.reputation + num_points + old_points = self.reputation + new_points = old_points + num_points if new_points > 0: self.reputation = new_points else: self.reputation = const.MIN_REPUTATION + signals.reputation_received.send(None, user=self, reputation_before=old_points) def user_update_wildcard_tag_selections( self, @@ -3681,8 +3682,7 @@ def make_admin_if_first_user(user, **kwargs): import sys user_count = User.objects.all().count() if user_count == 1: - user.set_admin_status() - user.save() + user.set_status('d') def moderate_group_joining(sender, instance=None, created=False, **kwargs): if created and instance.level == GroupMembership.PENDING: @@ -3700,6 +3700,13 @@ def tweet_new_post(sender, user=None, question=None, answer=None, form_data=None post = question or answer tweet_new_post_task.delay(post.id) +def autoapprove_reputable_user(user=None, reputation_before=None, *args, **kwargs): + """if user is 'watched' we change status to 'approved' + if user's rep crossed the auto-approval margin""" + margin = askbot_settings.MIN_REP_TO_AUTOAPPROVE_USER + if user.is_watched() and reputation_before < margin and user.reputation >= margin: + user.set_status('a') + def init_badge_data(sender, created_models=None, **kwargs): if BadgeData in created_models: from askbot.models import badges @@ -3740,6 +3747,7 @@ signals.user_logged_in.connect(post_anonymous_askbot_content) signals.post_updated.connect(record_post_update_activity) signals.new_answer_posted.connect(tweet_new_post) signals.new_question_posted.connect(tweet_new_post) +signals.reputation_received.connect(autoapprove_reputable_user) #probably we cannot use post-save here the point of this is #to tell when the revision becomes publicly visible, not when it is saved diff --git a/askbot/models/signals.py b/askbot/models/signals.py index 42a9c787..00152a0a 100644 --- a/askbot/models/signals.py +++ b/askbot/models/signals.py @@ -52,6 +52,7 @@ post_revision_published = django.dispatch.Signal( ] ) site_visited = django.dispatch.Signal(providing_args=['user', 'timestamp']) +reputation_received = django.dispatch.Signal(providing_args=['user', 'reputation_before']) def pop_signal_receivers(signal): """disables a given signal by removing listener functions diff --git a/askbot/templates/answer_edit.html b/askbot/templates/answer_edit.html index c9d8a147..bb43b83d 100644 --- a/askbot/templates/answer_edit.html +++ b/askbot/templates/answer_edit.html @@ -21,6 +21,10 @@ editor_type = settings.EDITOR_TYPE ) }} + {% if form.recaptcha %} + <div>{{ macros.form_fild_with_errors(form.recaptcha) }}</div> + <div class="clearfix"></div> + {% endif %} <div class="answer-options"> {% if settings.WIKI_ON and answer.wiki == False %} {{ macros.checkbox_in_div(form.wiki) }} diff --git a/askbot/templates/authopenid/complete.html b/askbot/templates/authopenid/complete.html index 21e6d039..4d4078d9 100644 --- a/askbot/templates/authopenid/complete.html +++ b/askbot/templates/authopenid/complete.html @@ -63,12 +63,9 @@ anyone, must be valid</i>) {% endif %} {{ openid_register_form.email }} </div> - {% if settings.USE_RECAPTCHA %} + {% if openid_register_form.recaptcha %} <div class="form-row-vertical"> - {% if openid_register_form.recaptcha.errors %} - <p class="error">{{ openid_register_form.recaptcha.errors|join(", ") }}</p> - {% endif %} - {{ openid_register_form.recaptcha }} + {{ macros.form_field_with_errors(openid_register_form.recaptcha ) }} </div> {% endif %} <div class="submit-row"> diff --git a/askbot/templates/authopenid/signup_with_password.html b/askbot/templates/authopenid/signup_with_password.html index c3625b62..ef8d8572 100644 --- a/askbot/templates/authopenid/signup_with_password.html +++ b/askbot/templates/authopenid/signup_with_password.html @@ -38,9 +38,8 @@ your login details with anyone and having to remember yet another password.{% en <li><label for="password1_id">{{form.password1.label}}</label>{{form.password1}}{{form.password1.errors}}</li> <li><label for="password2_id">{{form.password2.label}}</label>{{form.password2}}{{form.password2.errors}}</li> </ul> - {% if settings.USE_RECAPTCHA %} - <p class="signup_p">{% trans %}Please read and type in the two words below to help us prevent automated account creation.{% endtrans %}</p> - {{form.recaptcha}} + {% if form.recaptcha %} + {{ main_macros.form_field_with_errors(form.recaptcha) }} {% endif %} <div class="submit-row"><input id="signup-button" type="submit" class="button" value="{% trans %}Signup{% endtrans %}" /> {% if settings.PASSWORD_REGISTER_SHOW_PROVIDER_BUTTONS == False %} diff --git a/askbot/templates/feedback.html b/askbot/templates/feedback.html index 04b9a5b4..00453734 100644 --- a/askbot/templates/feedback.html +++ b/askbot/templates/feedback.html @@ -1,4 +1,5 @@ {% extends "two_column_body.html" %} +{% import "macros.html" as macros %} <!-- template feedback.html --> {% block title %}{% spaceless %}{% trans %}Feedback{% endtrans %}{% endspaceless %}{% endblock %} {% block content %} @@ -51,11 +52,7 @@ </div> {% if form.recaptcha %} <div class="form-row"> - {% if form.errors.recaptcha%} - <span class="error">{% trans %}(Please solve the captcha){% endtrans %}</span> - </label> - {% endif %} - {{form.recaptcha}} + {{ macros.form_field_with_errors(form.recaptcha) }} </div> {% endif %} {{form.next}} diff --git a/askbot/templates/macros.html b/askbot/templates/macros.html index 7ceb4eab..b314255c 100644 --- a/askbot/templates/macros.html +++ b/askbot/templates/macros.html @@ -848,3 +848,10 @@ for the purposes of the AJAX comment editor #} })(); </script> {% endmacro %} + +{% macro form_field_with_errors(field) %} + {% if field.errors %} + <p class="error">{{ field.errors|join(", ") }}</p> + {% endif %} + {{ field }} +{% endmacro %} diff --git a/askbot/templates/question/new_answer_form.html b/askbot/templates/question/new_answer_form.html index f8b4cd46..ae12738a 100644 --- a/askbot/templates/question/new_answer_form.html +++ b/askbot/templates/question/new_answer_form.html @@ -41,6 +41,10 @@ editor_type = settings.EDITOR_TYPE ) }} + {% if answer.recaptcha %} + <div>{{ macros.form_fild_with_errors(answer.recaptcha) }}</div> + <div class="clearfix"></div> + {% endif %} <input id="add-answer-btn" type="submit" class="submit after-editor" style="float:left"/> <script type="text/javascript"> askbot['functions']['renderAddAnswerButton'](); diff --git a/askbot/templates/question_edit.html b/askbot/templates/question_edit.html index e31050ec..db251fe6 100644 --- a/askbot/templates/question_edit.html +++ b/askbot/templates/question_edit.html @@ -35,6 +35,10 @@ ) }} <div class="after-editor"> + {% if form.recaptcha %} + <div>{{ macros.form_fild_with_errors(form.recaptcha) }}</div> + <div class="clearfix"></div> + {% endif %} <div class="question-options"> {% if settings.WIKI_ON and question.wiki == False %} {{ macros.checkbox_in_div(form.wiki) }} diff --git a/askbot/templates/widgets/ask_form.html b/askbot/templates/widgets/ask_form.html index df37ba3c..6e165857 100644 --- a/askbot/templates/widgets/ask_form.html +++ b/askbot/templates/widgets/ask_form.html @@ -61,6 +61,10 @@ </div> {% endif %} </div> + {% if form.recaptcha %} + <div>{{ macros.form_field_with_errors(form.recaptcha) }}</div> + <div class="clearfix"></div> + {% endif %} {% if not request.user.is_authenticated() %} <input type="submit" name="post_anon" value="{% trans %}Login/Signup to Post{% endtrans %}" class="submit" /> {% else %} diff --git a/askbot/views/meta.py b/askbot/views/meta.py index 8a91e72a..82a9e741 100644 --- a/askbot/views/meta.py +++ b/askbot/views/meta.py @@ -145,8 +145,10 @@ def feedback(request): request.user.message_set.create(message=msg) return HttpResponseRedirect(get_next_url(request)) else: - form = FeedbackForm(is_auth = request.user.is_authenticated(), - initial={'next':get_next_url(request)}) + form = FeedbackForm( + user=request.user, + initial={'next':get_next_url(request)} + ) data['form'] = form return render(request, 'feedback.html', data) |