Fixed authentication on search view
This commit is contained in:
parent
eb4673b3c4
commit
e4edb89d2c
2
TODO.md
2
TODO.md
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
Loading…
Reference in a new issue