Ejemplo n.º 1
0
def try_import(module_name, pypi_package_name):
    try:
        load_module(module_name)
    except ImportError, e:
        message = unicode(e) + ' run\npip install %s' % pypi_package_name
        message += '\nTo install all the dependencies at once, type:'
        message += '\npip install -r askbot_requirements.txt\n'
        raise ImproperlyConfigured(message)
def try_import(module_name, pypi_package_name):
    """tries importing a module and advises to install
    A corresponding Python package in the case import fails"""
    try:
        load_module(module_name)
    except ImportError, error:
        message = unicode(error) + ' run\npip install %s' % pypi_package_name
        message += '\nTo install all the dependencies at once, type:'
        message += '\npip install -r askbot_requirements.txt\n'
        raise ImproperlyConfigured(message)
Ejemplo n.º 3
0
def try_import(module_name, pypi_package_name):
    """tries importing a module and advises to install 
    A corresponding Python package in the case import fails"""
    try:
        load_module(module_name)
    except ImportError, error:
        message = unicode(error) + ' run\npip install %s' % pypi_package_name
        message += '\nTo install all the dependencies at once, type:'
        message += '\npip install -r askbot_requirements.txt\n'
        raise ImproperlyConfigured(message)
Ejemplo n.º 4
0
def try_import(module_name, pypi_package_name):
    """tries importing a module and advises to install
    A corresponding Python package in the case import fails"""
    try:
        load_module(module_name)
    except ImportError, error:
        message = 'Error: ' + unicode(error) 
        message += '\n\nPlease run: >pip install %s' % pypi_package_name
        message += '\n\nTo install all the dependencies at once, type:'
        message += '\npip install -r askbot_requirements.txt\n'
        message += '\nType ^C to quit.'
        raise AskbotConfigError(message)
Ejemplo n.º 5
0
def try_import(module_name, pypi_package_name, short_message = False):
    """tries importing a module and advises to install
    A corresponding Python package in the case import fails"""
    try:
        load_module(module_name)
    except ImportError, error:
        message = 'Error: ' + unicode(error)
        message += '\n\nPlease run: >pip install %s' % pypi_package_name
        if short_message == False:
            message += '\n\nTo install all the dependencies at once, type:'
            message += '\npip install -r askbot_requirements.txt'
        message += '\n\nType ^C to quit.'
        raise AskbotConfigError(message)
Ejemplo n.º 6
0
def test_custom_user_profile_tab():
    setting_name = 'ASKBOT_CUSTOM_USER_PROFILE_TAB'
    tab_settings = getattr(django_settings, setting_name, None)
    if tab_settings:
        if not isinstance(tab_settings, dict):
            print "Setting %s must be a dictionary!!!" % setting_name

        name = tab_settings.get('NAME', None)
        slug = tab_settings.get('SLUG', None)
        func_name = tab_settings.get('CONTENT_GENERATOR', None)

        errors = list()
        if (name is None) or (not(isinstance(name, basestring))):
            errors.append("%s['NAME'] must be a string" % setting_name)
        if (slug is None) or (not(isinstance(slug, str))):
            errors.append("%s['SLUG'] must be an ASCII string" % setting_name)

        if urllib.quote_plus(slug) != slug:
            errors.append(
                "%s['SLUG'] must be url safe, make it simple" % setting_name
            )

        try:
            func = load_module(func_name)
        except ImportError:
            errors.append("%s['CONTENT_GENERATOR'] must be a dotted path to a function" % setting_name)
        header = 'Custom user profile tab is configured incorrectly in your settings.py file'
        footer = 'Please carefully read about adding a custom user profile tab.'
        print_errors(errors, header = header, footer = footer)
Ejemplo n.º 7
0
def answer(request, id, form_class=forms.AnswerForm):#process a new answer
    """view that posts new answer

    anonymous users post into anonymous storage
    and redirected to login page

    authenticated users post directly
    """
    question = get_object_or_404(models.Post, post_type='question', id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(question.get_absolute_url())

    if request.method == "POST":

        #this check prevents backward compatilibility
        if form_class == forms.AnswerForm:
            custom_class_path = getattr(settings, 'ASKBOT_NEW_ANSWER_FORM', None)
            if custom_class_path:
                form_class = load_module(custom_class_path)
            else:
                form_class = forms.AnswerForm

        form = form_class(request.POST, user=request.user)

        if form.is_valid():
            if request.user.is_authenticated():
                drafts = models.DraftAnswer.objects.filter(
                                                author=request.user,
                                                thread=question.thread
                                            )
                drafts.delete()
                user = form.get_post_user(request.user)
                try:
                    answer = form.save(question, user)

                    signals.new_answer_posted.send(None,
                        answer=answer,
                        user=user,
                        form_data=form.cleaned_data
                    )

                    return HttpResponseRedirect(answer.get_absolute_url())
                except askbot_exceptions.AnswerAlreadyGiven, e:
                    request.user.message_set.create(message = unicode(e))
                    answer = question.thread.get_answers_by_user(user)[0]
                    return HttpResponseRedirect(answer.get_absolute_url())
                except exceptions.PermissionDenied, e:
                    request.user.message_set.create(message = unicode(e))
            else:
                request.session.flush()
                models.AnonymousAnswer.objects.create(
                    question=question,
                    wiki=form.cleaned_data['wiki'],
                    text=form.cleaned_data['text'],
                    session_key=request.session.session_key,
                    ip_addr=request.META['REMOTE_ADDR'],
                )
                return HttpResponseRedirect(url_utils.get_login_url())
Ejemplo n.º 8
0
def answer(request, id, form_class=forms.AnswerForm):  #process a new answer
    """view that posts new answer

    anonymous users post into anonymous storage
    and redirected to login page

    authenticated users post directly
    """
    question = get_object_or_404(models.Post, post_type='question', id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(question.get_absolute_url())

    if request.method == "POST":

        #this check prevents backward compatilibility
        if form_class == forms.AnswerForm:
            custom_class_path = getattr(settings, 'ASKBOT_NEW_ANSWER_FORM',
                                        None)
            if custom_class_path:
                form_class = load_module(custom_class_path)
            else:
                form_class = forms.AnswerForm

        form = form_class(request.POST, user=request.user)

        if form.is_valid():
            if request.user.is_authenticated():
                drafts = models.DraftAnswer.objects.filter(
                    author=request.user, thread=question.thread)
                drafts.delete()
                user = form.get_post_user(request.user)
                try:
                    answer = form.save(question,
                                       user,
                                       ip_addr=request.META.get('REMOTE_ADDR'))

                    signals.new_answer_posted.send(None,
                                                   answer=answer,
                                                   user=user,
                                                   form_data=form.cleaned_data)

                    return HttpResponseRedirect(answer.get_absolute_url())
                except askbot_exceptions.AnswerAlreadyGiven, e:
                    request.user.message_set.create(message=unicode(e))
                    answer = question.thread.get_answers_by_user(user)[0]
                    return HttpResponseRedirect(answer.get_absolute_url())
                except exceptions.PermissionDenied, e:
                    request.user.message_set.create(message=unicode(e))
            else:
                request.session.flush()
                models.AnonymousAnswer.objects.create(
                    question=question,
                    wiki=form.cleaned_data['wiki'],
                    text=form.cleaned_data['text'],
                    session_key=request.session.session_key,
                    ip_addr=request.META.get('REMOTE_ADDR'),
                )
                return HttpResponseRedirect(url_utils.get_login_url())
Ejemplo n.º 9
0
def get_federated_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `FEDERATED_REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'FEDERATED_REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    return RegistrationForm
Ejemplo n.º 10
0
def get_password_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `PASSWORD_REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'PASSWORD_REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    return PasswordRegistrationForm
Ejemplo n.º 11
0
def get_password_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `PASSWORD_REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'PASSWORD_REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    return PasswordRegistrationForm
Ejemplo n.º 12
0
def get_federated_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `FEDERATED_REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'FEDERATED_REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    return RegistrationForm
Ejemplo n.º 13
0
def get_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    else:
        return OpenidRegisterForm
Ejemplo n.º 14
0
def get_registration_form_class():
    """returns class for the user registration form
    user has a chance to specify the form via setting `REGISTRATION_FORM`
    """
    custom_class = getattr(django_settings, 'REGISTRATION_FORM', None)
    if custom_class:
        return load_module(custom_class)
    else:
        return OpenidRegisterForm
Ejemplo n.º 15
0
def dir_clashes_with_python_module(path):
    """Returns a boolean"""
    try:
        mod = load_module(os.path.basename(path))
    except ModuleNotFoundError:
        return False
    else:
        if path not in mod.__path__:
            return True
    return False
Ejemplo n.º 16
0
    def __init__(self, requirements = None):
        """loads the settings module and inits some variables
        parameter `requirements` is a dictionary with keys
        as setting names and values - another dictionary, which
        has keys (optional, if noted and required otherwise)::

        * required_value (optional)
        * error_message
        """
        self.settings = load_module(os.environ['DJANGO_SETTINGS_MODULE'])
        self.messages = list()
        self.requirements = requirements
Ejemplo n.º 17
0
    def __init__(self, requirements = None):
        """loads the settings module and inits some variables
        parameter `requirements` is a dictionary with keys
        as setting names and values - another dictionary, which
        has keys (optional, if noted and required otherwise)::

        * required_value (optional)
        * error_message
        """
        self.settings = load_module(os.environ['DJANGO_SETTINGS_MODULE'])
        self.messages = list()
        self.requirements = requirements
Ejemplo n.º 18
0
def user_custom_tab(request, user, context):
    """works only if `ASKBOT_CUSTOM_USER_PROFILE_TAB`
    setting in the ``settings.py`` is properly configured"""
    tab_settings = django_settings.ASKBOT_CUSTOM_USER_PROFILE_TAB
    module_path = tab_settings['CONTENT_GENERATOR']
    content_generator = load_module(module_path)

    page_title = _('profile - %(section)s') % \
        {'section': tab_settings['NAME']}

    context.update({
        'custom_tab_content': content_generator(request, user),
        'tab_name': tab_settings['SLUG'],
        'page_title': page_title
    })
    return render(request, 'user_profile/custom_tab.html', context)
Ejemplo n.º 19
0
def user_custom_tab(request, user, context):
    """works only if `ASKBOT_CUSTOM_USER_PROFILE_TAB`
    setting in the ``settings.py`` is properly configured"""
    tab_settings = django_settings.ASKBOT_CUSTOM_USER_PROFILE_TAB
    module_path = tab_settings['CONTENT_GENERATOR']
    content_generator = load_module(module_path)

    page_title = _('profile - %(section)s') % \
        {'section': tab_settings['NAME']}

    context.update({
        'custom_tab_content': content_generator(request, user),
        'tab_name': tab_settings['SLUG'],
        'page_title': page_title
    })
    return render(request, 'user_profile/custom_tab.html', context)
Ejemplo n.º 20
0
def user_custom_tab(request, user, context):
    """works only if `ASKBOT_CUSTOM_USER_PROFILE_TAB`
    setting in the ``settings.py`` is properly configured"""
    tab_settings = django_settings.ASKBOT_CUSTOM_USER_PROFILE_TAB
    module_path = tab_settings["CONTENT_GENERATOR"]
    content_generator = load_module(module_path)

    page_title = _("profile - %(section)s") % {"section": tab_settings["NAME"]}

    context.update(
        {
            "custom_tab_content": content_generator(request, user),
            "tab_name": tab_settings["SLUG"],
            "page_title": page_title,
        }
    )
    return render(request, "user_profile/custom_tab.html", context)
Ejemplo n.º 21
0
def extend_badge_events(e_to_b):
    mod_path = getattr(django_settings, 'ASKBOT_CUSTOM_BADGES', None)
    if mod_path:
        extra_e_to_b = load_module(mod_path)
        events = set(extra_e_to_b.keys())
        for event in events:
            if event not in e_to_b:
                raise ValueError('unkown badge event %s' % event)
            event_badges = set(e_to_b[event])
            extra_event_badges = set(extra_e_to_b[event])

            badge_keys = get_badge_keys(event_badges)
            extra_badge_keys = get_badge_keys(extra_event_badges)
            common_badge_keys = badge_keys & extra_badge_keys
            if len(common_badge_keys):
                info = ', '.join(common_badge_keys)
                raise ValueError('change key values of custom badges: %s' % info)

            event_badges.update(extra_event_badges)
            e_to_b[event] = event_badges
    return e_to_b
Ejemplo n.º 22
0
def extend_badge_events(e_to_b):
    mod_path = getattr(django_settings, 'ASKBOT_CUSTOM_BADGES', None)
    if mod_path:
        extra_e_to_b = load_module(mod_path)
        events = set(extra_e_to_b.keys())
        for event in events:
            if event not in e_to_b:
                raise ValueError('unkown badge event %s' % event)
            event_badges = set(e_to_b[event])
            extra_event_badges = set(extra_e_to_b[event])

            badge_keys = get_badge_keys(event_badges)
            extra_badge_keys = get_badge_keys(extra_event_badges)
            common_badge_keys = badge_keys & extra_badge_keys
            if len(common_badge_keys):
                info = ', '.join(common_badge_keys)
                raise ValueError('change key values of custom badges: %s' % info)

            event_badges.update(extra_event_badges)
            e_to_b[event] = event_badges
    return e_to_b
Ejemplo n.º 23
0
 def load_context_processors(cls, paths):
     processors = list()
     for path in paths:
         processors.append(load_module(path))
     return processors
Ejemplo n.º 24
0
        is_cacheable = False

    #maybe load draft
    initial = {}
    if request.user.is_authenticated():
        #todo: refactor into methor on thread
        drafts = models.DraftAnswer.objects.filter(
                                        author=request.user,
                                        thread=thread
                                    )
        if drafts.count() > 0:
            initial['text'] = drafts[0].get_text()

    custom_answer_form_path = getattr(django_settings, 'ASKBOT_NEW_ANSWER_FORM', None)
    if custom_answer_form_path:
        answer_form_class = load_module(custom_answer_form_path)
    else:
        answer_form_class = AnswerForm

    answer_form = answer_form_class(initial=initial, user=request.user)

    user_can_post_comment = (
        request.user.is_authenticated() \
        and request.user.can_post_comment(question_post)
    )

    new_answer_allowed = True
    previous_answer = None
    if request.user.is_authenticated():
        if askbot_settings.LIMIT_ONE_ANSWER_PER_USER:
            for answer in answers:
Ejemplo n.º 25
0
def signin(request, template_name='authopenid/signin.html'):
    """
    signin page. It manages the legacy authentification (user/password)
    and openid authentification

    url: /signin/

    template : authopenid/signin.htm
    """
    logging.debug('in signin view')
    on_failure = signin_failure

    #we need a special priority on where to redirect on successful login
    #here:
    #1) url parameter "next" - if explicitly set
    #2) url from django setting LOGIN_REDIRECT_URL
    #3) home page of the forum
    login_redirect_url = getattr(django_settings, 'LOGIN_REDIRECT_URL', None)
    next_url = get_next_url(request, default = login_redirect_url)
    logging.debug('next url is %s' % next_url)

    if askbot_settings.ALLOW_ADD_REMOVE_LOGIN_METHODS == False \
        and request.user.is_authenticated():
        return HttpResponseRedirect(next_url)

    if next_url == reverse('user_signin'):
        next_url = '%(next)s?next=%(next)s' % {'next': next_url}

    login_form = forms.LoginForm(initial = {'next': next_url})

    #todo: get next url make it sticky if next is 'user_signin'
    if request.method == 'POST':

        login_form = forms.LoginForm(request.POST)
        if login_form.is_valid():

            provider_name = login_form.cleaned_data['login_provider_name']
            if login_form.cleaned_data['login_type'] == 'password':

                password_action = login_form.cleaned_data['password_action']
                if askbot_settings.USE_LDAP_FOR_PASSWORD_LOGIN:
                    assert(password_action == 'login')
                    username = login_form.cleaned_data['username']
                    password = login_form.cleaned_data['password']

                    user = authenticate(
                                    username=username,
                                    password=password,
                                    method = 'ldap'
                                )

                    if user:
                        login(request, user)
                        return HttpResponseRedirect(next_url)
                    else:
                        #try to login again via LDAP
                        user_info = ldap_authenticate(username, password)
                        if user_info['success']:
                            if askbot_settings.LDAP_AUTOCREATE_USERS:
                                #create new user or 
                                user = ldap_create_user(user_info).user
                                user = authenticate(method='force', user_id=user.id)
                                assert(user is not None)
                                login(request, user)
                                return HttpResponseRedirect(next_url)
                            else:
                                #continue with proper registration
                                ldap_username = user_info['ldap_username']
                                request.session['email'] = user_info['email']
                                request.session['ldap_user_info'] = user_info
                                if askbot_settings.AUTOFILL_USER_DATA:
                                    request.session['username'] = ldap_username
                                    request.session['first_name'] = \
                                        user_info['first_name']
                                    request.session['last_name'] = \
                                        user_info['last_name']
                                return finalize_generic_signin(
                                    request,
                                    login_provider_name = 'ldap', 
                                    user_identifier = ldap_username + '@ldap',
                                    redirect_url = next_url
                                )
                        else:
                            auth_fail_func_path = getattr(
                                                django_settings,
                                                'LDAP_AUTHENTICATE_FAILURE_FUNCTION',
                                                None
                                            )

                            if auth_fail_func_path:
                                auth_fail_func = load_module(auth_fail_func_path)
                                auth_fail_func(user_info, login_form)
                            else:
                                login_form.set_password_login_error()
                            #return HttpResponseRedirect(request.path)
                else:
                    if password_action == 'login':
                        user = authenticate(
                                username = login_form.cleaned_data['username'],
                                password = login_form.cleaned_data['password'],
                                provider_name = provider_name,
                                method = 'password'
                            )
                        if user is None:
                            login_form.set_password_login_error()
                        else:
                            login(request, user)
                            #todo: here we might need to set cookies
                            #for external login sites
                            return HttpResponseRedirect(next_url)
                    elif password_action == 'change_password':
                        if request.user.is_authenticated():
                            new_password = \
                                login_form.cleaned_data['new_password']
                            AuthBackend.set_password(
                                            user=request.user,
                                            password=new_password,
                                            provider_name=provider_name
                                        )
                            request.user.message_set.create(
                                        message = _('Your new password saved')
                                    )
                            return HttpResponseRedirect(next_url)
                    else:
                        logging.critical(
                            'unknown password action %s' % password_action
                        )
                        raise Http404

            elif login_form.cleaned_data['login_type'] == 'openid':
                #initiate communication process
                logging.debug('processing signin with openid submission')

                #todo: make a simple-use wrapper for openid protocol

                sreg_req = sreg.SRegRequest(optional=['nickname', 'email'])
                redirect_to = "%s%s?%s" % (
                        get_url_host(request),
                        reverse('user_complete_signin'),
                        urllib.urlencode({'next':next_url})
                )
                return ask_openid(
                            request,
                            login_form.cleaned_data['openid_url'],
                            redirect_to,
                            on_failure=signin_failure,
                            sreg_request=sreg_req
                        )

            elif login_form.cleaned_data['login_type'] == 'oauth':
                try:
                    #this url may need to have "next" piggibacked onto
                    callback_url = reverse('user_complete_oauth_signin')

                    connection = util.OAuthConnection(
                                        provider_name,
                                        callback_url = callback_url
                                    )

                    connection.start()

                    request.session['oauth_token'] = connection.get_token()
                    request.session['oauth_provider_name'] = provider_name
                    request.session['next_url'] = next_url#special case for oauth

                    oauth_url = connection.get_auth_url(login_only = False)
                    return HttpResponseRedirect(oauth_url)

                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _('Unfortunately, there was some problem when '
                            'connecting to %(provider)s, please try again '
                            'or use another provider'
                        ) % {'provider': provider_name}
                    request.user.message_set.create(message = msg)

            elif login_form.cleaned_data['login_type'] == 'facebook':
                #have to redirect for consistency
                #there is a requirement that 'complete_signin'
                try:
                    #this call may raise FacebookError
                    user_id = util.get_facebook_user_id(request)

                    user = authenticate(
                                method = 'facebook',
                                facebook_user_id = user_id
                            )

                    return finalize_generic_signin(
                                    request = request,
                                    user = user,
                                    user_identifier = user_id,
                                    login_provider_name = provider_name,
                                    redirect_url = next_url
                                )

                except util.FacebookError, e:
                    logging.critical(unicode(e))
                    msg = _('Unfortunately, there was some problem when '
                            'connecting to %(provider)s, please try again '
                            'or use another provider'
                        ) % {'provider': 'Facebook'}
                    request.user.message_set.create(message = msg)

            elif login_form.cleaned_data['login_type'] == 'wordpress_site':
                #here wordpress_site means for a self hosted wordpress blog not a wordpress.com blog
                wp = Client(askbot_settings.WORDPRESS_SITE_URL, login_form.cleaned_data['username'], login_form.cleaned_data['password'])
                try:
                    wp_user = wp.call(GetUserInfo())
                    custom_wp_openid_url = '%s?user_id=%s' % (wp.url, wp_user.user_id)
                    user = authenticate(
                            method = 'wordpress_site',
                            wordpress_url = wp.url,
                            wp_user_id = wp_user.user_id
                           )
                    return finalize_generic_signin(
                                    request = request,
                                    user = user,
                                    user_identifier = custom_wp_openid_url,
                                    login_provider_name = provider_name,
                                    redirect_url = next_url
                                    )
                except WpFault, e:
                    logging.critical(unicode(e))
                    msg = _('The login password combination was not correct')
                    request.user.message_set.create(message = msg)
Ejemplo n.º 26
0
def edit_answer(request, id):
    answer = get_object_or_404(models.Post, id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(answer.get_absolute_url())

    try:
        revision = answer.revisions.get(revision=0)
    except models.PostRevision.DoesNotExist:
        revision = answer.get_latest_revision()

    class_path = getattr(settings, 'ASKBOT_EDIT_ANSWER_FORM', None)
    if class_path:
        edit_answer_form_class = load_module(class_path)
    else:
        edit_answer_form_class = forms.EditAnswerForm

    try:
        request.user.assert_can_edit_answer(answer)
        if request.method == "POST":
            if request.POST['select_revision'] == 'true':
                # user has changed revistion number
                revision_form = forms.RevisionForm(
                                                answer,
                                                revision,
                                                request.POST
                                            )
                if revision_form.is_valid():
                    # Replace with those from the selected revision
                    rev = revision_form.cleaned_data['revision']
                    revision = answer.revisions.get(revision = rev)
                    form = edit_answer_form_class(
                                    answer, revision, user=request.user
                                )
                else:
                    form = edit_answer_form_class(
                                                answer,
                                                revision,
                                                request.POST,
                                                user=request.user
                                            )
            else:
                form = edit_answer_form_class(
                    answer, revision, request.POST, user=request.user
                )
                revision_form = forms.RevisionForm(answer, revision)

                if form.is_valid():
                    if form.has_changed():
                        user = form.get_post_user(request.user)
                        suppress_email = form.cleaned_data['suppress_email']
                        is_private = form.cleaned_data.get('post_privately', False)
                        user.edit_answer(
                            answer=answer,
                            body_text=form.cleaned_data['text'],
                            revision_comment=form.cleaned_data['summary'],
                            wiki=form.cleaned_data.get('wiki', answer.wiki),
                            is_private=is_private,
                            suppress_email=suppress_email,
                            ip_addr=request.META.get('REMOTE_ADDR')
                        )

                        signals.answer_edited.send(None,
                            answer=answer,
                            user=user,
                            form_data=form.cleaned_data
                        )

                    return HttpResponseRedirect(answer.get_absolute_url())
        else:
            revision_form = forms.RevisionForm(answer, revision)
            form = edit_answer_form_class(answer, revision, user=request.user)
            if request.user.can_make_group_private_posts():
                form.initial['post_privately'] = answer.is_private()

        data = {
            'page_class': 'edit-answer-page',
            'active_tab': 'questions',
            'answer': answer,
            'revision': revision,
            'revision_form': revision_form,
            'form': form,
        }
        extra_context = context.get_extra(
            'ASKBOT_EDIT_ANSWER_PAGE_EXTRA_CONTEXT',
            request,
            data
        )
        data.update(extra_context)

        return render(request, 'answer_edit.html', data)

    except exceptions.PermissionDenied, e:
        request.user.message_set.create(message = unicode(e))
        return HttpResponseRedirect(answer.get_absolute_url())
Ejemplo n.º 27
0
def get_extra(context_module_setting, request, data):
    extra_context = getattr(django_settings, context_module_setting, None)
    if extra_context:
        extra_context_getter = load_module(extra_context)
        return extra_context_getter(request, data)
    return {}
Ejemplo n.º 28
0
def edit_answer(request, id):
    answer = get_object_or_404(models.Post, id=id)
    revision = answer.get_latest_revision()

    class_path = getattr(settings, 'ASKBOT_EDIT_ANSWER_FORM', None)
    if class_path:
        edit_answer_form_class = load_module(class_path)
    else:
        edit_answer_form_class = forms.EditAnswerForm

    try:
        request.user.assert_can_edit_answer(answer)
        if request.method == "POST":
            if request.POST['select_revision'] == 'true':
                # user has changed revistion number
                revision_form = forms.RevisionForm(answer, revision,
                                                   request.POST)
                if revision_form.is_valid():
                    # Replace with those from the selected revision
                    rev = revision_form.cleaned_data['revision']
                    revision = answer.revisions.get(revision=rev)
                    form = edit_answer_form_class(answer,
                                                  revision,
                                                  user=request.user)
                else:
                    form = edit_answer_form_class(answer,
                                                  revision,
                                                  request.POST,
                                                  user=request.user)
            else:
                form = edit_answer_form_class(answer,
                                              revision,
                                              request.POST,
                                              user=request.user)
                revision_form = forms.RevisionForm(answer, revision)

                if form.is_valid():
                    if form.has_changed():
                        user = form.get_post_user(request.user)
                        suppress_email = form.cleaned_data['suppress_email']
                        is_private = form.cleaned_data.get(
                            'post_privately', False)
                        user.edit_answer(
                            answer=answer,
                            body_text=form.cleaned_data['text'],
                            revision_comment=form.cleaned_data['summary'],
                            wiki=form.cleaned_data.get('wiki', answer.wiki),
                            is_private=is_private,
                            suppress_email=suppress_email)

                        signals.answer_edited.send(None,
                                                   answer=answer,
                                                   user=user,
                                                   form_data=form.cleaned_data)

                    return HttpResponseRedirect(answer.get_absolute_url())
        else:
            revision_form = forms.RevisionForm(answer, revision)
            form = edit_answer_form_class(answer, revision, user=request.user)
            if request.user.can_make_group_private_posts():
                form.initial['post_privately'] = answer.is_private()

        data = {
            'page_class': 'edit-answer-page',
            'active_tab': 'questions',
            'answer': answer,
            'revision': revision,
            'revision_form': revision_form,
            'form': form,
        }
        extra_context = context.get_extra(
            'ASKBOT_EDIT_ANSWER_PAGE_EXTRA_CONTEXT', request, data)
        data.update(extra_context)

        return render(request, 'answer_edit.html', data)

    except exceptions.PermissionDenied, e:
        request.user.message_set.create(message=unicode(e))
        return HttpResponseRedirect(answer.get_absolute_url())
Ejemplo n.º 29
0
def question(request, id):  # refactor - long subroutine. display question body, answers and comments
    """view that displays body of the question and
    all answers to it

    TODO: convert this view into class
    """
    # process url parameters
    # TODO: fix inheritance of sort method from questions

    form = ShowQuestionForm(dict(tuple(request.POST.items()) + tuple(request.GET.items())))

    form.full_clean()  # always valid
    show_answer = form.cleaned_data['show_answer']
    show_comment = form.cleaned_data['show_comment']
    show_page = form.cleaned_data['show_page']
    answer_sort_method = form.cleaned_data['answer_sort_method']

    # load question and maybe refuse showing deleted question
    # if the question does not exist - try mapping to old questions
    # and and if it is not found again - then give up

    qs = Post.objects.filter(post_type='question').select_related('thread')

    question_post = qs.filter(id=id).first()
    if question_post is None:
        # Handle URL mapping - from old Q/A/C/ URLs to the new one
        question_post = qs.filter(old_question_id=id).first()
        if question_post is None:
            raise Http404

        if show_answer:
            try:
                old_answer = Post.objects.get_answers().get(old_answer_id=show_answer)
            except Post.DoesNotExist:
                pass
            else:
                return redirect(old_answer)

        elif show_comment:
            try:
                old_comment = Post.objects.get_comments().get(old_comment_id=show_comment)
            except Post.DoesNotExist:
                pass
            else:
                return redirect(old_comment)

    if show_comment or show_answer:
        try:
            show_post = Post.objects.get(pk=(show_comment or show_answer))
        except Post.DoesNotExist:
            # missing target post will be handled later
            pass
        else:
            if (show_comment and not show_post.is_comment()) or \
                    (show_answer and not show_post.is_answer()):
                return redirect(show_post)

    try:
        question_post.assert_is_visible_to(request.user)
    except exceptions.QuestionHidden as error:
        traceback.print_exc()
        # request.user.message_set.create(message=force_text(error))
        django_messages.info(request, force_text(error))
        return redirect('index')

    # redirect if slug in the url is wrong
    if request.path.split('/')[-2] != question_post.slug:
        logging.debug('no slug match!')
        lang = translation.get_language()
        question_url = question_post.get_absolute_url(language=lang)
        if request.GET:
            question_url += '?' + urlencode(request.GET)
        return redirect(question_url)

    # resolve comment and answer permalinks
    # they go first because in theory both can be moved to another question
    # this block "returns" show_post and assigns actual comment and answer
    # to show_comment and show_answer variables
    # in the case if the permalinked items or their parents are gone - redirect
    # redirect also happens if id of the object's origin post != requested id
    show_post = None  # used for permalinks
    if show_comment:
        # if url calls for display of a specific comment,
        # check that comment exists, that it belongs to
        # the current question
        # if it is an answer comment and the answer is hidden -
        # redirect to the default view of the question
        # if the question is hidden - redirect to the main page
        # in addition - if url points to a comment and the comment
        # is for the answer - we need the answer object
        try:
            show_comment = Post.objects.get_comments().get(id=show_comment)
        except Post.DoesNotExist as e:
            traceback.print_exc()
            error_message = _(
                'Sorry, the comment you are looking for has been '
                'deleted and is no longer accessible'
            )
            # request.user.message_set.create(message=error_message)
            django_messages.info(request, error_message)
            return redirect(question_post.thread)

        if str(show_comment.thread._question_post().id) != str(id):
            return redirect(show_comment)
        show_post = show_comment.parent

        try:
            show_comment.assert_is_visible_to(request.user)
        except exceptions.AnswerHidden as e:
            traceback.print_exc()
            # request.user.message_set.create(message=force_text(e))
            django_messages.info(request, force_text(e))
            # use reverse function here because question is not yet loaded
            return redirect('question', id=id)
        except exceptions.QuestionHidden as e:
            traceback.print_exc()
            # request.user.message_set.create(message=force_text(e))
            django_messages.info(request, force_text(e))
            return redirect('index')

    elif show_answer:
        # if the url calls to view a particular answer to
        # question - we must check whether the question exists
        # whether answer is actually corresponding to the current question
        # and that the visitor is allowed to see it
        show_post = get_object_or_404(Post, post_type='answer', id=show_answer)
        if str(show_post.thread._question_post().id) != str(id):
            return redirect(show_post)

        try:
            show_post.assert_is_visible_to(request.user)
        except django_exceptions.PermissionDenied as e:
            traceback.print_exc()
            # request.user.message_set.create(message=force_text(e))
            django_messages.info(request, force_text(e))
            return redirect('question', id=id)

    thread = question_post.thread

    logging.debug('answer_sort_method=' + force_text(answer_sort_method))

    # load answers and post id's->athor_id mapping
    # posts are pre-stuffed with the correctly ordered comments
    question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view(
        sort_method=answer_sort_method,
        user=request.user)
    user_votes = {}
    user_post_id_list = list()

    # TODO: cache this query set, but again takes only 3ms!
    if request.user.is_authenticated():
        user_votes = Vote.objects.\
            filter(user=request.user, voted_post__id__in=post_to_author.keys()).\
            values_list('voted_post_id', 'vote')
        user_votes = dict(user_votes)
        # we can avoid making this query by iterating through
        # already loaded posts
        user_post_id_list = [
            post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id
        ]

    # resolve page number and comment number for permalinks
    show_comment_position = None
    if show_comment:
        show_page = show_comment.get_page_number(answer_posts=answers)
        show_comment_position = show_comment.get_order_number()
    elif show_answer:
        show_page = show_post.get_page_number(answer_posts=answers)

    objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE)
    if show_page > objects_list.num_pages:
        return redirect(question_post)
    page_objects = objects_list.page(show_page)

    # count visits
    signals.question_visited.send(None, request=request, question=question_post)

    paginator_data = {
        'is_paginated': (objects_list.count > const.ANSWERS_PAGE_SIZE),
        'pages': objects_list.num_pages,
        'current_page_number': show_page,
        'page_object': page_objects,
        'base_url': request.path + '?sort=%s&' % answer_sort_method,
    }
    paginator_context = functions.setup_paginator(paginator_data)

    # TODO: maybe consolidate all activity in the thread
    # for the user into just one query?
    favorited = thread.has_favorite_by_user(request.user)

    is_cacheable = True
    if show_page != 1:
        is_cacheable = False
    elif (show_comment_position or 0) > askbot_settings.MAX_COMMENTS_TO_SHOW:
        is_cacheable = False

    # maybe load draft
    initial = {}
    if request.user.is_authenticated():
        # TODO: refactor into methor on thread
        drafts = DraftAnswer.objects.filter(author=request.user, thread=thread)
        if drafts.count() > 0:
            initial['text'] = drafts[0].text

    custom_answer_form_path = getattr(django_settings, 'ASKBOT_NEW_ANSWER_FORM', None)
    if custom_answer_form_path:
        answer_form_class = load_module(custom_answer_form_path)
    else:
        answer_form_class = AnswerForm

    answer_form = answer_form_class(initial=initial, user=request.user)

    user_can_post_comment = (request.user.is_authenticated() and request.user.can_post_comment(question_post))

    new_answer_allowed = True
    previous_answer = None
    if request.user.is_authenticated():
        if askbot_settings.LIMIT_ONE_ANSWER_PER_USER:
            for answer in answers:
                if answer.author_id == request.user.pk:
                    new_answer_allowed = False
                    previous_answer = answer
                    break

    if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED:
        group_read_only = request.user.is_read_only()
    else:
        group_read_only = False

    data = {
        'active_tab': 'questions',
        'answer': answer_form,
        'answers': page_objects.object_list,
        'answer_count': thread.get_answer_count(request.user),
        'blank_comment': MockPost(post_type='comment', author=request.user),  # data for the js comment template
        'category_tree_data': askbot_settings.CATEGORY_TREE,
        'editor_is_unfolded': answer_form.has_data(),
        'favorited': favorited,
        'group_read_only': group_read_only,
        'is_cacheable': False,  # is_cacheable, # temporary, until invalidation fix
        'language_code': translation.get_language(),
        'long_time': const.LONG_TIME,  # "forever" caching
        'new_answer_allowed': new_answer_allowed,
        'oldest_answer_id': thread.get_oldest_answer_id(request.user),
        'page_class': 'question-page',
        'paginator_context': paginator_context,
        'previous_answer': previous_answer,
        'published_answer_ids': published_answer_ids,
        'question': question_post,
        'show_comment': show_comment,
        'show_comment_position': show_comment_position,
        'show_post': show_post,
        'similar_threads': thread.get_similar_threads(),
        'tab_id': answer_sort_method,
        'thread': thread,
        'thread_is_moderated': thread.is_moderated(),
        'user_is_thread_moderator': thread.has_moderator(request.user),
        'user_votes': user_votes,
        'user_post_id_list': user_post_id_list,
        'user_can_post_comment': user_can_post_comment,  # in general
    }

    # shared with ...
    if askbot_settings.GROUPS_ENABLED:
        data['sharing_info'] = thread.get_sharing_info()

    data.update(context.get_for_tag_editor())

    extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data)
    data.update(extra)

    return render(request, 'question.jinja', data)
Ejemplo n.º 30
0
def question(request, id):#refactor - long subroutine. display question body, answers and comments
    """view that displays body of the question and
    all answers to it

    todo: convert this view into class
    """
    #process url parameters
    #todo: fix inheritance of sort method from questions
    #before = timezone.now()
    form = ShowQuestionForm(request.REQUEST)
    form.full_clean()#always valid
    show_answer = form.cleaned_data['show_answer']
    show_comment = form.cleaned_data['show_comment']
    show_page = form.cleaned_data['show_page']
    answer_sort_method = form.cleaned_data['answer_sort_method']

    #load question and maybe refuse showing deleted question
    #if the question does not exist - try mapping to old questions
    #and and if it is not found again - then give up
    try:
        question_post = models.Post.objects.filter(
                                post_type = 'question',
                                id = id
                            ).select_related('thread')[0]
    except IndexError:
    # Handle URL mapping - from old Q/A/C/ URLs to the new one
        try:
            question_post = models.Post.objects.filter(
                                    post_type='question',
                                    old_question_id = id
                                ).select_related('thread')[0]
        except IndexError:
            raise Http404

        if show_answer:
            try:
                old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer)
            except models.Post.DoesNotExist:
                pass
            else:
                return HttpResponseRedirect(old_answer.get_absolute_url())

        elif show_comment:
            try:
                old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment)
            except models.Post.DoesNotExist:
                pass
            else:
                return HttpResponseRedirect(old_comment.get_absolute_url())

    if show_comment or show_answer:
        try:
            show_post = models.Post.objects.get(pk=(show_comment or show_answer))
        except models.Post.DoesNotExist:
            #missing target post will be handled later
            pass
        else:
            if (show_comment and not show_post.is_comment()) \
                or (show_answer and not show_post.is_answer()):
                return HttpResponseRedirect(show_post.get_absolute_url())

    try:
        question_post.assert_is_visible_to(request.user)
    except exceptions.QuestionHidden as error:
        request.user.message_set.create(message = unicode(error))
        return HttpResponseRedirect(reverse('index'))

    #redirect if slug in the url is wrong
    if request.path.split('/')[-2] != question_post.slug:
        logging.debug('no slug match!')
        lang = translation.get_language()
        question_url = question_post.get_absolute_url(language=lang)
        if request.GET:
            question_url += u'?' + urllib.urlencode(request.GET)
        return HttpResponseRedirect(question_url)


    #resolve comment and answer permalinks
    #they go first because in theory both can be moved to another question
    #this block "returns" show_post and assigns actual comment and answer
    #to show_comment and show_answer variables
    #in the case if the permalinked items or their parents are gone - redirect
    #redirect also happens if id of the object's origin post != requested id
    show_post = None #used for permalinks
    if show_comment:
        #if url calls for display of a specific comment,
        #check that comment exists, that it belongs to
        #the current question
        #if it is an answer comment and the answer is hidden -
        #redirect to the default view of the question
        #if the question is hidden - redirect to the main page
        #in addition - if url points to a comment and the comment
        #is for the answer - we need the answer object
        try:
            show_comment = models.Post.objects.get_comments().get(id=show_comment)
        except models.Post.DoesNotExist:
            error_message = _(
                'Sorry, the comment you are looking for has been '
                'deleted and is no longer accessible'
            )
            request.user.message_set.create(message = error_message)
            return HttpResponseRedirect(question_post.thread.get_absolute_url())

        if str(show_comment.thread._question_post().id) != str(id):
            return HttpResponseRedirect(show_comment.get_absolute_url())
        show_post = show_comment.parent

        try:
            show_comment.assert_is_visible_to(request.user)
        except exceptions.AnswerHidden as error:
            request.user.message_set.create(message = unicode(error))
            #use reverse function here because question is not yet loaded
            return HttpResponseRedirect(reverse('question', kwargs = {'id': id}))
        except exceptions.QuestionHidden as error:
            request.user.message_set.create(message = unicode(error))
            return HttpResponseRedirect(reverse('index'))

    elif show_answer:
        #if the url calls to view a particular answer to
        #question - we must check whether the question exists
        #whether answer is actually corresponding to the current question
        #and that the visitor is allowed to see it
        show_post = get_object_or_404(models.Post, post_type='answer', id=show_answer)
        if str(show_post.thread._question_post().id) != str(id):
            return HttpResponseRedirect(show_post.get_absolute_url())

        try:
            show_post.assert_is_visible_to(request.user)
        except django_exceptions.PermissionDenied as error:
            request.user.message_set.create(message = unicode(error))
            return HttpResponseRedirect(reverse('question', kwargs = {'id': id}))

    thread = question_post.thread

    if askbot.get_lang_mode() == 'url-lang':
        request_lang = translation.get_language()
        if request_lang != thread.language_code:
            template = get_template('question/lang_switch_message.html')
            message = template.render(Context({
                'post_lang': get_language_name(thread.language_code),
                'request_lang': get_language_name(request_lang),
                'home_url': reverse_i18n(request_lang, 'questions')
            }))
            request.user.message_set.create(message=message)
            return HttpResponseRedirect(thread.get_absolute_url())

    logging.debug('answer_sort_method=' + unicode(answer_sort_method))

    #load answers and post id's->athor_id mapping
    #posts are pre-stuffed with the correctly ordered comments
    question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view(
                                sort_method=answer_sort_method,
                                user=request.user
                            )
    user_votes = {}
    user_post_id_list = list()
    #todo: cache this query set, but again takes only 3ms!
    if request.user.is_authenticated():
        user_votes = Vote.objects.filter(
                            user=request.user,
                            voted_post__id__in = post_to_author.keys()
                        ).values_list('voted_post_id', 'vote')
        user_votes = dict(user_votes)
        #we can avoid making this query by iterating through
        #already loaded posts
        user_post_id_list = [
            post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id
        ]

    #resolve page number and comment number for permalinks
    show_comment_position = None
    if show_comment:
        show_page = show_comment.get_page_number(answer_posts=answers)
        show_comment_position = show_comment.get_order_number()
    elif show_answer:
        show_page = show_post.get_page_number(answer_posts=answers)

    objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE)
    if show_page > objects_list.num_pages:
        return HttpResponseRedirect(question_post.get_absolute_url())
    page_objects = objects_list.page(show_page)

    #count visits
    signals.question_visited.send(None,
                    request=request,
                    question=question_post,
                )

    paginator_data = {
        'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE),
        'pages': objects_list.num_pages,
        'current_page_number': show_page,
        'page_object': page_objects,
        'base_url' : request.path + '?sort=%s&' % answer_sort_method,
    }
    paginator_context = functions.setup_paginator(paginator_data)

    #todo: maybe consolidate all activity in the thread
    #for the user into just one query?
    favorited = thread.has_favorite_by_user(request.user)

    is_cacheable = True
    if show_page != 1:
        is_cacheable = False
    elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW:
        is_cacheable = False

    #maybe load draft
    initial = {}
    if request.user.is_authenticated():
        #todo: refactor into methor on thread
        drafts = models.DraftAnswer.objects.filter(
                                        author=request.user,
                                        thread=thread
                                    )
        if drafts.count() > 0:
            initial['text'] = drafts[0].get_text()

    custom_answer_form_path = django_settings.ASKBOT_NEW_ANSWER_FORM
    if custom_answer_form_path:
        answer_form_class = load_module(custom_answer_form_path)
    else:
        answer_form_class = AnswerForm

    answer_form = answer_form_class(initial=initial, user=request.user)

    user_can_post_comment = (
        request.user.is_authenticated() \
        and request.user.can_post_comment(question_post)
    )

    new_answer_allowed = True
    previous_answer = None
    if request.user.is_authenticated():
        if askbot_settings.LIMIT_ONE_ANSWER_PER_USER:
            for answer in answers:
                if answer.author_id == request.user.pk:
                    new_answer_allowed = False
                    previous_answer = answer
                    break

    if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED:
        group_read_only = request.user.is_read_only()
    else:
        group_read_only = False

    #session variable added so that the session is
    #not empty and is not autodeleted, otherwise anonymous
    #answer posting is impossible
    request.session['askbot_write_intent'] = True

    data = {
        'active_tab': 'questions',
        'answer' : answer_form,
        'answers' : page_objects.object_list,
        'answer_count': thread.get_answer_count(request.user),
        'blank_comment': MockPost(post_type='comment', author=request.user),#data for the js comment template
        'category_tree_data': askbot_settings.CATEGORY_TREE,
        'favorited' : favorited,
        'group_read_only': group_read_only,
        'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix
        'language_code': translation.get_language(),
        'long_time': const.LONG_TIME,#"forever" caching
        'new_answer_allowed': new_answer_allowed,
        'oldest_answer_id': thread.get_oldest_answer_id(request.user),
        'page_class': 'question-page',
        'paginator_context' : paginator_context,
        'previous_answer': previous_answer,
        'published_answer_ids': published_answer_ids,
        'question' : question_post,
        'show_comment': show_comment,
        'show_comment_position': show_comment_position,
        'show_post': show_post,
        'similar_threads' : thread.get_similar_threads(),
        'tab_id' : answer_sort_method,
        'thread': thread,
        'thread_is_moderated': thread.is_moderated(),
        'user_is_thread_moderator': thread.has_moderator(request.user),
        'user_votes': user_votes,
        'user_post_id_list': user_post_id_list,
        'user_can_post_comment': user_can_post_comment,#in general
    }
    #shared with ...
    if askbot_settings.GROUPS_ENABLED:
        data['sharing_info'] = thread.get_sharing_info()

    data.update(context.get_for_tag_editor())

    extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data)
    data.update(extra)

    return render(request, 'question.html', data)
Ejemplo n.º 31
0
        is_cacheable = False

    #maybe load draft
    initial = {}
    if request.user.is_authenticated():
        #todo: refactor into methor on thread
        drafts = models.DraftAnswer.objects.filter(
                                        author=request.user,
                                        thread=thread
                                    )
        if drafts.count() > 0:
            initial['text'] = drafts[0].text

    custom_answer_form_path = getattr(django_settings, 'ASKBOT_NEW_ANSWER_FORM', None)
    if custom_answer_form_path:
        answer_form_class = load_module(custom_answer_form_path)
    else:
        answer_form_class = AnswerForm

    answer_form = answer_form_class(initial=initial, user=request.user)

    user_can_post_comment = (
        request.user.is_authenticated() \
        and request.user.can_post_comment(question_post)
    )

    new_answer_allowed = True
    previous_answer = None
    if request.user.is_authenticated():
        if askbot_settings.LIMIT_ONE_ANSWER_PER_USER:
            for answer in answers:
Ejemplo n.º 32
0
 def __init__(self, login_module_path):
     from askbot.utils.loading import load_module
     self.mod = load_module(login_module_path)
     self.mod_path = login_module_path
     self.read_params()
Ejemplo n.º 33
0
def answer(request, id, form_class=forms.AnswerForm):#process a new answer
    """view that posts new answer

    anonymous users post into anonymous storage
    and redirected to login page

    authenticated users post directly
    """
    question = get_object_or_404(models.Post, post_type='question', id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(question.get_absolute_url())

    if request.method == 'GET':
        #session key used only to enable anonymous asking
        #as django will autodelete empty sessions
        request.session['askbot_write_intent'] = True
    elif request.method == 'POST':

        #this check prevents backward compatilibility
        if form_class == forms.AnswerForm:
            custom_class_path = getattr(settings, 'ASKBOT_NEW_ANSWER_FORM', None)
            if custom_class_path:
                form_class = load_module(custom_class_path)
            else:
                form_class = forms.AnswerForm

        form = form_class(request.POST, user=request.user)

        if form.is_valid():
            if request.user.is_authenticated():
                drafts = models.DraftAnswer.objects.filter(
                                                author=request.user,
                                                thread=question.thread
                                            )
                drafts.delete()
                user = form.get_post_user(request.user)
                try:
                    text = form.cleaned_data['text']
                    if akismet_check_spam(text, request):
                        message = _('Spam was detected on your post, sorry if it was a mistake')
                        raise exceptions.PermissionDenied(message)

                    answer = form.save(
                                    question,
                                    user,
                                    ip_addr=request.META.get('REMOTE_ADDR')
                                )

                    signals.new_answer_posted.send(None,
                        answer=answer,
                        user=user,
                        form_data=form.cleaned_data
                    )

                    return HttpResponseRedirect(answer.get_absolute_url())
                except askbot_exceptions.AnswerAlreadyGiven as e:
                    request.user.message_set.create(message = unicode(e))
                    answer = question.thread.get_answers_by_user(user)[0]
                    return HttpResponseRedirect(answer.get_absolute_url())
                except exceptions.PermissionDenied as e:
                    request.user.message_set.create(message = unicode(e))
            else:
                if request.session.session_key is None:
                    return HttpResponseForbidden()

                models.AnonymousAnswer.objects.create(
                    question=question,
                    wiki=form.cleaned_data['wiki'],
                    text=form.cleaned_data['text'],
                    session_key=request.session.session_key,
                    ip_addr=request.META.get('REMOTE_ADDR'),
                )
                return HttpResponseRedirect(url_utils.get_login_url())

    #TODO: look into an issue here is that backend form validation errors
    # won't be displayed, we are fully relying on the prevalidation
    # in the js
    return HttpResponseRedirect(question.get_absolute_url())
Ejemplo n.º 34
0
def edit_answer(request, id):
    answer = get_object_or_404(models.Post, id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(answer.get_absolute_url())

    revision = answer.get_latest_revision()

    class_path = getattr(settings, "ASKBOT_EDIT_ANSWER_FORM", None)
    if class_path:
        edit_answer_form_class = load_module(class_path)
    else:
        edit_answer_form_class = forms.EditAnswerForm

    try:
        request.user.assert_can_edit_answer(answer)
        if request.method == "POST":
            if request.POST["select_revision"] == "true":
                # user has changed revistion number
                revision_form = forms.RevisionForm(answer, revision, request.POST)
                if revision_form.is_valid():
                    # Replace with those from the selected revision
                    rev = revision_form.cleaned_data["revision"]
                    revision = answer.revisions.get(revision=rev)
                    form = edit_answer_form_class(answer, revision, user=request.user)
                else:
                    form = edit_answer_form_class(answer, revision, request.POST, user=request.user)
            else:
                form = edit_answer_form_class(answer, revision, request.POST, user=request.user)
                revision_form = forms.RevisionForm(answer, revision)

                if form.is_valid():
                    if form.has_changed():
                        user = form.get_post_user(request.user)
                        suppress_email = form.cleaned_data["suppress_email"]
                        is_private = form.cleaned_data.get("post_privately", False)
                        user.edit_answer(
                            answer=answer,
                            body_text=form.cleaned_data["text"],
                            revision_comment=form.cleaned_data["summary"],
                            wiki=form.cleaned_data.get("wiki", answer.wiki),
                            is_private=is_private,
                            suppress_email=suppress_email,
                            ip_addr=request.META.get("REMOTE_ADDR"),
                        )

                        signals.answer_edited.send(None, answer=answer, user=user, form_data=form.cleaned_data)

                    return HttpResponseRedirect(answer.get_absolute_url())
        else:
            revision_form = forms.RevisionForm(answer, revision)
            form = edit_answer_form_class(answer, revision, user=request.user)
            if request.user.can_make_group_private_posts():
                form.initial["post_privately"] = answer.is_private()

        data = {
            "page_class": "edit-answer-page",
            "active_tab": "questions",
            "answer": answer,
            "revision": revision,
            "revision_form": revision_form,
            "form": form,
        }
        extra_context = context.get_extra("ASKBOT_EDIT_ANSWER_PAGE_EXTRA_CONTEXT", request, data)
        data.update(extra_context)

        return render(request, "answer_edit.html", data)

    except exceptions.PermissionDenied, e:
        request.user.message_set.create(message=unicode(e))
        return HttpResponseRedirect(answer.get_absolute_url())
Ejemplo n.º 35
0
    user.username = user_info.get('django_username', user_info['ldap_username'])
    user.set_unusable_password()
    user.first_name = user_info['first_name']
    user.last_name = user_info['last_name']
    user.email = user_info['email']
    user.is_staff = False
    user.is_superuser = False
    user.is_active = True
    user.save()
    user_registered.send(None, user=user, request=request)
    LOG.info('Created New User : [{0}]'.format(user_info['ldap_username']))

    assoc = UserAssociation()
    assoc.user = user
    assoc.openid_url = user_info['ldap_username'] + '@ldap'
    assoc.provider_name = 'ldap'
    assoc.save()
    return assoc

LDAP_AUTH_FUNC_PATH = getattr(django_settings, 'LDAP_AUTHENTICATE_FUNCTION', None)
if LDAP_AUTH_FUNC_PATH:
    ldap_authenticate = load_module(LDAP_AUTH_FUNC_PATH)
else:
    ldap_authenticate = ldap_authenticate_default

LDAP_CREATE_FUNC_PATH = getattr(django_settings, 'LDAP_CREATE_USER_FUNCTION', None)
if LDAP_CREATE_FUNC_PATH:
    ldap_create_user = load_module(LDAP_CREATE_FUNC_PATH)
else:
    ldap_create_user = ldap_create_user_default
Ejemplo n.º 36
0
def answer(request, id, form_class=forms.AnswerForm):  #process a new answer
    """view that posts new answer

    anonymous users post into anonymous storage
    and redirected to login page

    authenticated users post directly
    """
    question = get_object_or_404(models.Post, post_type='question', id=id)

    if askbot_settings.READ_ONLY_MODE_ENABLED:
        return HttpResponseRedirect(question.get_absolute_url())

    if request.method == 'GET':
        #session key used only to enable anonymous asking
        #as django will autodelete empty sessions
        request.session['askbot_write_intent'] = True
    elif request.method == 'POST':

        #this check prevents backward compatilibility
        if form_class == forms.AnswerForm:
            custom_class_path = getattr(settings, 'ASKBOT_NEW_ANSWER_FORM',
                                        None)
            if custom_class_path:
                form_class = load_module(custom_class_path)
            else:
                form_class = forms.AnswerForm

        form = form_class(request.POST, user=request.user)

        if form.is_valid():
            if request.user.is_authenticated():
                drafts = models.DraftAnswer.objects.filter(
                    author=request.user, thread=question.thread)
                drafts.delete()
                user = form.get_post_user(request.user)
                try:
                    text = form.cleaned_data['text']
                    if akismet_check_spam(text, request):
                        message = _(
                            'Spam was detected on your post, sorry if it was a mistake'
                        )
                        raise exceptions.PermissionDenied(message)

                    answer = form.save(question,
                                       user,
                                       ip_addr=request.META.get('REMOTE_ADDR'))

                    signals.new_answer_posted.send(None,
                                                   answer=answer,
                                                   user=user,
                                                   form_data=form.cleaned_data)

                    return HttpResponseRedirect(answer.get_absolute_url())
                except askbot_exceptions.AnswerAlreadyGiven as e:
                    request.user.message_set.create(message=unicode(e))
                    answer = question.thread.get_answers_by_user(user)[0]
                    return HttpResponseRedirect(answer.get_absolute_url())
                except exceptions.PermissionDenied as e:
                    request.user.message_set.create(message=unicode(e))
            else:
                if request.session.session_key is None:
                    return HttpResponseForbidden()

                models.AnonymousAnswer.objects.create(
                    question=question,
                    wiki=form.cleaned_data['wiki'],
                    text=form.cleaned_data['text'],
                    session_key=request.session.session_key,
                    ip_addr=request.META.get('REMOTE_ADDR'),
                )
                return HttpResponseRedirect(url_utils.get_login_url())

    #TODO: look into an issue here is that backend form validation errors
    # won't be displayed, we are fully relying on the prevalidation
    # in the js
    return HttpResponseRedirect(question.get_absolute_url())
Ejemplo n.º 37
0
 def __init__(self, login_module_path):
     self.mod = load_module(login_module_path)
     self.mod_path = login_module_path
     self.read_params()
Ejemplo n.º 38
0
def get_extra(context_module_setting, request, data):
    extra_context = getattr(django_settings, context_module_setting, None)
    if extra_context:
        extra_context_getter = load_module(extra_context)
        return extra_context_getter(request, data)
    return {}
Ejemplo n.º 39
0
def signin(request, template_name="authopenid/signin.html"):
    """
    signin page. It manages the legacy authentification (user/password)
    and openid authentification

    url: /signin/

    template : authopenid/signin.htm
    """
    logging.debug("in signin view")
    on_failure = signin_failure

    # we need a special priority on where to redirect on successful login
    # here:
    # 1) url parameter "next" - if explicitly set
    # 2) url from django setting LOGIN_REDIRECT_URL
    # 3) home page of the forum
    login_redirect_url = getattr(django_settings, "LOGIN_REDIRECT_URL", None)
    next_url = get_next_url(request, default=login_redirect_url)
    logging.debug("next url is %s" % next_url)

    if askbot_settings.ALLOW_ADD_REMOVE_LOGIN_METHODS == False and request.user.is_authenticated():
        return HttpResponseRedirect(next_url)

    if next_url == reverse("user_signin"):
        next_url = "%(next)s?next=%(next)s" % {"next": next_url}

    login_form = forms.LoginForm(initial={"next": next_url})

    # todo: get next url make it sticky if next is 'user_signin'
    if request.method == "POST":

        login_form = forms.LoginForm(request.POST)
        if login_form.is_valid():

            provider_name = login_form.cleaned_data["login_provider_name"]
            if login_form.cleaned_data["login_type"] == "password":

                password_action = login_form.cleaned_data["password_action"]
                if askbot_settings.USE_LDAP_FOR_PASSWORD_LOGIN:
                    assert password_action == "login"
                    username = login_form.cleaned_data["username"]
                    password = login_form.cleaned_data["password"]

                    user = authenticate(username=username, password=password, method="ldap")

                    if user:
                        login(request, user)
                        return HttpResponseRedirect(next_url)
                    else:
                        # try to login again via LDAP
                        user_info = ldap_authenticate(username, password)
                        if user_info["success"]:
                            if askbot_settings.LDAP_AUTOCREATE_USERS:
                                # create new user or
                                user = ldap_create_user(user_info).user
                                user = authenticate(method="force", user_id=user.id)
                                assert user is not None
                                login(request, user)
                                return HttpResponseRedirect(next_url)
                            else:
                                # continue with proper registration
                                ldap_username = user_info["ldap_username"]
                                request.session["email"] = user_info["email"]
                                request.session["ldap_user_info"] = user_info
                                if askbot_settings.AUTOFILL_USER_DATA:
                                    request.session["username"] = ldap_username
                                    request.session["first_name"] = user_info["first_name"]
                                    request.session["last_name"] = user_info["last_name"]
                                return finalize_generic_signin(
                                    request,
                                    login_provider_name="ldap",
                                    user_identifier=ldap_username + "@ldap",
                                    redirect_url=next_url,
                                )
                        else:
                            auth_fail_func_path = getattr(django_settings, "LDAP_AUTHENTICATE_FAILURE_FUNCTION", None)

                            if auth_fail_func_path:
                                auth_fail_func = load_module(auth_fail_func_path)
                                auth_fail_func(user_info, login_form)
                            else:
                                login_form.set_password_login_error()
                            # return HttpResponseRedirect(request.path)
                else:
                    if password_action == "login":
                        user = authenticate(
                            username=login_form.cleaned_data["username"],
                            password=login_form.cleaned_data["password"],
                            provider_name=provider_name,
                            method="password",
                        )
                        if user is None:
                            login_form.set_password_login_error()
                        else:
                            login(request, user)
                            # todo: here we might need to set cookies
                            # for external login sites
                            return HttpResponseRedirect(next_url)
                    elif password_action == "change_password":
                        if request.user.is_authenticated():
                            new_password = login_form.cleaned_data["new_password"]
                            AuthBackend.set_password(
                                user=request.user, password=new_password, provider_name=provider_name
                            )
                            request.user.message_set.create(message=_("Your new password saved"))
                            return HttpResponseRedirect(next_url)
                    else:
                        logging.critical("unknown password action %s" % password_action)
                        raise Http404

            elif login_form.cleaned_data["login_type"] == "openid":
                # initiate communication process
                logging.debug("processing signin with openid submission")

                # todo: make a simple-use wrapper for openid protocol

                sreg_req = sreg.SRegRequest(optional=["nickname", "email"])
                redirect_to = "%s%s?%s" % (
                    get_url_host(request),
                    reverse("user_complete_signin"),
                    urllib.urlencode({"next": next_url}),
                )
                return ask_openid(
                    request,
                    login_form.cleaned_data["openid_url"],
                    redirect_to,
                    on_failure=signin_failure,
                    sreg_request=sreg_req,
                )

            elif login_form.cleaned_data["login_type"] == "oauth":
                try:
                    # this url may need to have "next" piggibacked onto
                    connection = util.OAuthConnection(provider_name, callback_url=reverse("user_complete_oauth_signin"))

                    connection.start()

                    request.session["oauth_token"] = connection.get_token()
                    request.session["oauth_provider_name"] = provider_name
                    request.session["next_url"] = next_url  # special case for oauth

                    oauth_url = connection.get_auth_url(login_only=True)
                    return HttpResponseRedirect(oauth_url)

                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _(
                        "Unfortunately, there was some problem when "
                        "connecting to %(provider)s, please try again "
                        "or use another provider"
                    ) % {"provider": provider_name}
                    request.user.message_set.create(message=msg)

            elif login_form.cleaned_data["login_type"] == "oauth2":
                try:
                    csrf_token = generate_random_key(length=32)
                    redirect_url = util.get_oauth2_starter_url(provider_name, csrf_token)
                    request.session["oauth2_csrf_token"] = csrf_token
                    request.session["provider_name"] = provider_name
                    return HttpResponseRedirect(redirect_url)
                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _(
                        "Unfortunately, there was some problem when "
                        "connecting to %(provider)s, please try again "
                        "or use another provider"
                    ) % {"provider": provider_name}
                    request.user.message_set.create(message=msg)

            elif login_form.cleaned_data["login_type"] == "wordpress_site":
                # here wordpress_site means for a self hosted wordpress blog not a wordpress.com blog
                wp = Client(
                    askbot_settings.WORDPRESS_SITE_URL,
                    login_form.cleaned_data["username"],
                    login_form.cleaned_data["password"],
                )
                try:
                    wp_user = wp.call(GetUserInfo())
                    custom_wp_openid_url = "%s?user_id=%s" % (wp.url, wp_user.user_id)
                    user = authenticate(method="wordpress_site", wordpress_url=wp.url, wp_user_id=wp_user.user_id)
                    return finalize_generic_signin(
                        request=request,
                        user=user,
                        user_identifier=custom_wp_openid_url,
                        login_provider_name=provider_name,
                        redirect_url=next_url,
                    )
                except WpFault, e:
                    logging.critical(unicode(e))
                    msg = _("The login password combination was not correct")
                    request.user.message_set.create(message=msg)
Ejemplo n.º 40
0
 def __init__(self, login_module_path):
     self.mod = load_module(login_module_path)
     self.mod_path = login_module_path
     self.read_params()
Ejemplo n.º 41
0
    """takes the result returned by the :func:`ldap_authenticate`

    and returns a :class:`UserAssociation` object
    """
    # create new user in local db
    user = User()
    user.username = user_info.get('django_username', user_info['ldap_username'])
    user.set_unusable_password()
    user.first_name = user_info['first_name']
    user.last_name = user_info['last_name']
    user.email = user_info['email']
    user.is_staff = False
    user.is_superuser = False
    user.is_active = True
    user.save()
    user_registered.send(None, user = user)
    LOG.info('Created New User : [{0}]'.format(user_info['ldap_username']))

    assoc = UserAssociation()
    assoc.user = user
    assoc.openid_url = user_info['ldap_username']
    assoc.provider_name = 'Wind River LDAP'
    assoc.save()
    return assoc

LDAP_AUTH_FUNC_PATH = getattr(django_settings, 'LDAP_AUTHENTICATE_FUNCTION', None)
if LDAP_AUTH_FUNC_PATH:
    ldap_authenticate = load_module(LDAP_AUTH_FUNC_PATH)
else:
    ldap_authenticate = ldap_authenticate_default
Ejemplo n.º 42
0
 def load_context_processors(cls, paths):
     processors = list()
     for path in paths:
         processors.append(load_module(path))
     return processors
Ejemplo n.º 43
0
 def __init__(self, login_module_path):
     from askbot.utils.loading import load_module
     self.mod = load_module(login_module_path)
     self.mod_path = login_module_path
     self.read_params()
Ejemplo n.º 44
0
def answer(request, id):#process a new answer
    """view that posts new answer

    anonymous users post into anonymous storage
    and redirected to login page

    authenticated users post directly
    """
    question = get_object_or_404(models.Post, post_type='question', id=id)
    if request.method == "POST":

        custom_class_path = getattr(settings, 'ASKBOT_NEW_ANSWER_FORM', None)
        if custom_class_path:
            form_class = load_module(custom_class_path)
        else:
            form_class = forms.AnswerForm

        form = form_class(request.POST, user=request.user)

        if form.is_valid():
            wiki = form.cleaned_data['wiki']
            text = form.cleaned_data['text']
            update_time = datetime.datetime.now()

            if request.user.is_authenticated():
                drafts = models.DraftAnswer.objects.filter(
                                                author=request.user,
                                                thread=question.thread
                                            )
                drafts.delete()
                try:
                    follow = form.cleaned_data['email_notify']
                    is_private = form.cleaned_data['post_privately']

                    user = form.get_post_user(request.user)

                    answer = user.post_answer(
                                        question = question,
                                        body_text = text,
                                        follow = follow,
                                        wiki = wiki,
                                        is_private = is_private,
                                        timestamp = update_time,
                                    )

                    signals.new_answer_posted.send(None,
                        answer=answer,
                        user=user,
                        form_data=form.cleaned_data
                    )

                    return HttpResponseRedirect(answer.get_absolute_url())
                except askbot_exceptions.AnswerAlreadyGiven, e:
                    request.user.message_set.create(message = unicode(e))
                    answer = question.thread.get_answers_by_user(request.user)[0]
                    return HttpResponseRedirect(answer.get_absolute_url())
                except exceptions.PermissionDenied, e:
                    request.user.message_set.create(message = unicode(e))
            else:
                request.session.flush()
                models.AnonymousAnswer.objects.create(
                    question=question,
                    wiki=wiki,
                    text=text,
                    session_key=request.session.session_key,
                    ip_addr=request.META['REMOTE_ADDR'],
                )
                return HttpResponseRedirect(url_utils.get_login_url())