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?
# 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 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 .options import *
from ..core import accounts, services
# 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
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.admin.utils import unquote
from django.contrib.auth import admin as auth
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.templatetags.static import static
from django.utils.safestring import mark_safe
@ -152,6 +153,14 @@ class AccountListAdmin(AccountAdmin):
if hasattr(response, 'context_data'):
# user has submitted a change list change, we redirect directly to the add view
# 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
if len(queryset) == 1:
return HttpResponseRedirect('../?account=%i' % queryset[0].pk)

View file

@ -1,5 +1,6 @@
{% load i18n admin_tools_menu_tags %}
{% if menu.children %}
<script type="text/javascript" src="{{ media_url }}/admin_tools/js/utils.js"></script>
<script type="text/javascript" charset="utf-8">
// Load js files syncronously and conditionally
@ -48,8 +49,11 @@
<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>
{% 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;">
<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 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.">
</form>
<span style="float:right;color:grey;margin:10px;font-size:11px;">
{% url 'admin:accounts_account_change' user.pk as user_change_url %}

View file

@ -24,7 +24,7 @@ urlpatterns = [
'orchestra.views.serve_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.contrib import admin
from django.contrib.admin.utils import unquote
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.db.models import get_model
from django.shortcuts import get_object_or_404, render, redirect
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
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):
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)
else:
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)