Fixed authentication on search view

This commit is contained in:
Marc Aymerich 2015-10-08 09:00:22 +00:00
parent eb4673b3c4
commit e4edb89d2c
6 changed files with 74 additions and 62 deletions

View file

@ -423,4 +423,4 @@ mkhomedir_helper or create ssh homes with bash.rc and such
# account contacts inline, show provided fields and ignore the rest? # account contacts inline, show provided fields and ignore the rest?
# email usage -webkit-column-count:3;-moz-column-count:3;column-count:3; # email usage -webkit-column-count:3;-moz-column-count:3;column-count:3;
# resources on service report # Protect fucking search url and put into /admin/search and admin.py

View file

@ -1,9 +1,16 @@
import itertools
from collections import OrderedDict
from functools import update_wrapper from functools import update_wrapper
from django.contrib import admin from django.contrib import admin
from django.core.urlresolvers import reverse
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from .dashboard import * from .dashboard import *
from .options import * from .options import *
from ..core import accounts, services
# monkey-patch admin.site in order to porvide some extra admin urls # monkey-patch admin.site in order to porvide some extra admin urls
@ -30,3 +37,52 @@ def get_urls():
) )
return site_get_urls() + extra_patterns return site_get_urls() + extra_patterns
admin.site.get_urls = get_urls admin.site.get_urls = get_urls
def search(request):
query = request.GET.get('q', '')
if query.endswith('!'):
from ..contrib.accounts.models import Account
# Account direct access
query = query.replace('!', '')
try:
account = Account.objects.get(username=query)
except Account.DoesNotExist:
pass
else:
account_url = reverse('admin:accounts_account_change', args=(account.pk,))
return redirect(account_url)
results = OrderedDict()
models = set()
for service in itertools.chain(services, accounts):
if service.search:
models.add(service.model)
models = sorted(models, key=lambda m: m._meta.verbose_name_plural.lower())
total = 0
for model in models:
try:
modeladmin = admin.site._registry[model]
except KeyError:
pass
else:
qs = modeladmin.get_queryset(request)
qs, search_use_distinct = modeladmin.get_search_results(request, qs, query)
if search_use_distinct:
qs = qs.distinct()
num = len(qs)
if num:
total += num
results[model._meta] = qs
title = _("{total} search results for '<tt>{query}</tt>'").format(total=total, query=query)
context = {
'title': mark_safe(title),
'total': total,
'columns': min(int(total/17), 3),
'query': query,
'results': results,
'search_autofocus': True,
}
return render(request, 'admin/orchestra/search.html', context)
admin.site.register_url(r'^search/$', search, 'orchestra_search_view')

View file

@ -8,6 +8,7 @@ from django.conf.urls import url
from django.contrib import admin, messages from django.contrib import admin, messages
from django.contrib.admin.utils import unquote from django.contrib.admin.utils import unquote
from django.contrib.auth import admin as auth from django.contrib.auth import admin as auth
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -152,6 +153,14 @@ class AccountListAdmin(AccountAdmin):
if hasattr(response, 'context_data'): if hasattr(response, 'context_data'):
# user has submitted a change list change, we redirect directly to the add view # user has submitted a change list change, we redirect directly to the add view
# if there is only one result # if there is only one result
query = request.GET.get('q', '')
if query:
try:
account = Account.objects.get(username=query)
except Account.DoesNotExist:
pass
else:
return HttpResponseRedirect('../?account=%i' % account.pk)
queryset = response.context_data['cl'].queryset queryset = response.context_data['cl'].queryset
if len(queryset) == 1: if len(queryset) == 1:
return HttpResponseRedirect('../?account=%i' % queryset[0].pk) return HttpResponseRedirect('../?account=%i' % queryset[0].pk)

View file

@ -1,5 +1,6 @@
{% load i18n admin_tools_menu_tags %} {% load i18n admin_tools_menu_tags %}
{% if menu.children %} {% if menu.children %}
<script type="text/javascript" src="{{ media_url }}/admin_tools/js/utils.js"></script> <script type="text/javascript" src="{{ media_url }}/admin_tools/js/utils.js"></script>
<script type="text/javascript" charset="utf-8"> <script type="text/javascript" charset="utf-8">
// Load js files syncronously and conditionally // Load js files syncronously and conditionally
@ -48,8 +49,11 @@
<div style="max-width: 1170px; margin:auto;"> <div style="max-width: 1170px; margin:auto;">
<div id="branding"><a href="/admin/"></a><h1 id="site-name"><a href="/admin/">{{ ORCHESTRA_SITE_VERBOSE_NAME }}<span class="version">0.0.1a1</span></a></h1></div> <div id="branding"><a href="/admin/"></a><h1 id="site-name"><a href="/admin/">{{ ORCHESTRA_SITE_VERBOSE_NAME }}<span class="version">0.0.1a1</span></a></h1></div>
{% for item in menu.children %}{% admin_tools_render_menu_item item forloop.counter %}{% endfor %} {% for item in menu.children %}{% admin_tools_render_menu_item item forloop.counter %}{% endfor %}
<form action="/search" method="get" name="top_search" style="display: inline;"> <form action="{% url 'admin:orchestra_search_view' %}" method="get" name="top_search" style="display: inline;">
<input type="text" id="searchbox" style="margin-left:15px;margin-top:7px;" name="q" placeholder="Search" size="25" value="{{ query }}" {% if search_autofocus or app_list %}autofocus="autofocus"{% endif %} title="Use 'username!' for account direct access."> <input type="text" id="searchbox" style="margin-left:15px;margin-top:7px;" name="q"
placeholder="Search" size="25" value="{{ query }}"
{% if search_autofocus or app_list %}autofocus="autofocus"{% endif %}
title="Use 'username!' for account direct access.">
</form> </form>
<span style="float:right;color:grey;margin:10px;font-size:11px;"> <span style="float:right;color:grey;margin:10px;font-size:11px;">
{% url 'admin:accounts_account_change' user.pk as user_change_url %} {% url 'admin:accounts_account_change' user.pk as user_change_url %}

View file

@ -24,7 +24,7 @@ urlpatterns = [
'orchestra.views.serve_private_media', 'orchestra.views.serve_private_media',
name='private-media' name='private-media'
), ),
url(r'search', 'orchestra.views.search', name='search'), # url(r'search', 'orchestra.views.search', name='search'),
] ]

View file

@ -1,22 +1,10 @@
import itertools
from collections import OrderedDict
from django.http import Http404 from django.http import Http404
from django.contrib import admin
from django.contrib.admin.utils import unquote from django.contrib.admin.utils import unquote
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.db.models import get_model from django.db.models import get_model
from django.shortcuts import get_object_or_404, render, redirect from django.shortcuts import get_object_or_404
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.views.static import serve from django.views.static import serve
from orchestra.contrib.accounts.models import Account
from .core import accounts, services
from .utils.python import OrderedSet
def serve_private_media(request, app_label, model_name, field_name, object_id, filename): def serve_private_media(request, app_label, model_name, field_name, object_id, filename):
model = get_model(app_label, model_name) model = get_model(app_label, model_name)
@ -30,48 +18,3 @@ def serve_private_media(request, app_label, model_name, field_name, object_id, f
return serve(request, field.name, document_root=field.storage.location) return serve(request, field.name, document_root=field.storage.location)
else: else:
raise PermissionDenied() raise PermissionDenied()
def search(request):
query = request.GET.get('q', '')
if query.endswith('!'):
# Account direct access
query = query.replace('!', '')
try:
account = Account.objects.get(username=query)
except Account.DoesNotExist:
pass
else:
account_url = reverse('admin:accounts_account_change', args=(account.pk,))
return redirect(account_url)
results = OrderedDict()
models = set()
for service in itertools.chain(services, accounts):
if service.search:
models.add(service.model)
models = sorted(models, key=lambda m: m._meta.verbose_name_plural.lower())
total = 0
for model in models:
try:
modeladmin = admin.site._registry[model]
except KeyError:
pass
else:
qs = modeladmin.get_queryset(request)
qs, search_use_distinct = modeladmin.get_search_results(request, qs, query)
if search_use_distinct:
qs = qs.distinct()
num = len(qs)
if num:
total += num
results[model._meta] = qs
title = _("{total} search results for '<tt>{query}</tt>'").format(total=total, query=query)
context = {
'title': mark_safe(title),
'total': total,
'columns': min(int(total/17), 3),
'query': query,
'results': results,
'search_autofocus': True,
}
return render(request, 'admin/orchestra/search.html', context)