Mercurial > public > sg101
changeset 961:840c1a8bd8af
Mitigate QueryParserError when searching.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 03 Aug 2015 17:26:32 -0500 |
parents | fc4a1c4e488a |
children | 10e7570a3aab |
files | custom_search/views.py sg101/templates/search/search.html |
diffstat | 2 files changed, 51 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/custom_search/views.py Mon Jul 13 18:24:41 2015 -0500 +++ b/custom_search/views.py Mon Aug 03 17:26:32 2015 -0500 @@ -1,13 +1,19 @@ """Custom views for searching.""" +import logging +from django.shortcuts import render_to_response from haystack.views import SearchView +from xapian import QueryParserError +logger = logging.getLogger(__name__) class UserSearchView(SearchView): """This class passes the user making the search as an __init__ argument to the search form as the keyword argument 'user'. """ + query_parser_error = False + def build_form(self, form_kwargs=None): """Pass the request.user object to the form's constructor.""" if not form_kwargs: @@ -15,3 +21,35 @@ if 'user' not in form_kwargs: form_kwargs['user'] = self.request.user return super(UserSearchView, self).build_form(form_kwargs) + + # This nonsense is because Xapian can raise QueryParserError when evaluating + # the query. This was triggered by some sh*t-bag looking for SQL injection + # vulnerabilities. + # If QueryParserError is raised, just drive on and set a flag in the context + # (via extra_context()) so that an error is rendered on the template instead + # of a 500 error. + + def create_response(self): + try: + return super(UserSearchView, self).create_response() + except QueryParserError: + self.query_parser_error = True + + logger.warning("QueryParserError triggered from user search input") + + context = { + 'query': self.query, + 'form': self.form, + 'page': None, + 'paginator': None, + 'suggestion': None, + } + + context.update(self.extra_context()) + return render_to_response(self.template, context, + context_instance=self.context_class(self.request)) + + def extra_context(self): + return { + 'query_parser_error': self.query_parser_error, + }
--- a/sg101/templates/search/search.html Mon Jul 13 18:24:41 2015 -0500 +++ b/sg101/templates/search/search.html Mon Aug 03 17:26:32 2015 -0500 @@ -27,6 +27,18 @@ {% endblock %} {% block content %} <h2>Search <img src="{{ STATIC_URL }}icons/magnifier.png" alt="Search" /></h2> +{% if query_parser_error %} +<div class="error"> + <p> + Your search query could not be processed. This is most likely because you've + included terms like AND, OR, or NOT. These terms are not necessary. + </p> + <p> + If you continue to have problems with this error, please + <a href="{% url 'contact-form' %}?subject=Search%20Help">contact us</a>. + </p> +</div> +{% endif %} <form id="search-form" method="get" action="."> <fieldset> <legend>Find content with:</legend> @@ -44,7 +56,7 @@ </fieldset> </form> -{% if form.is_valid %} +{% if form.is_valid and not query_parser_error %} <h3>Search results; page {{ page.number }} of {{ page.paginator.num_pages }}</h3> {% if page.paginator.count %}