mirror of
https://github.com/ansible/awx.git
synced 2024-11-02 01:21:21 +03:00
AC-1040 Fix broken dashboard view. Add backwards-compatible support for old project and inventory source filters.
This commit is contained in:
parent
5d6dbc6e6b
commit
6504a8ae40
@ -49,7 +49,18 @@ class FieldLookupBackend(BaseFilterBackend):
|
||||
# FIXME: Could build up a list of models used across relationships, use
|
||||
# those lookups combined with request.user.get_queryset(Model) to make
|
||||
# sure user cannot query using objects he could not view.
|
||||
new_parts = []
|
||||
for n, name in enumerate(parts[:-1]):
|
||||
|
||||
# HACK: Make project and inventory source filtering by old field names work for backwards compatibility.
|
||||
if model._meta.object_name in ('Project', 'InventorySource'):
|
||||
name = {
|
||||
'current_update': 'current_job',
|
||||
'last_update': 'last_job',
|
||||
'last_update_failed': 'last_job_failed',
|
||||
'last_updated': 'last_job_run',
|
||||
}.get(name, name)
|
||||
|
||||
if name == 'pk':
|
||||
field = model._meta.pk
|
||||
else:
|
||||
@ -59,7 +70,11 @@ class FieldLookupBackend(BaseFilterBackend):
|
||||
model = field.rel.to
|
||||
else:
|
||||
model = field.model
|
||||
return field
|
||||
new_parts.append(name)
|
||||
if parts:
|
||||
new_parts.append(parts[-1])
|
||||
new_lookup = '__'.join(new_parts)
|
||||
return field, new_lookup
|
||||
|
||||
def to_python_boolean(self, value, allow_none=False):
|
||||
value = unicode(value)
|
||||
@ -90,7 +105,7 @@ class FieldLookupBackend(BaseFilterBackend):
|
||||
return field.to_python(value)
|
||||
|
||||
def value_to_python(self, model, lookup, value):
|
||||
field = self.get_field_from_lookup(model, lookup)
|
||||
field, new_lookup = self.get_field_from_lookup(model, lookup)
|
||||
if lookup.endswith('__isnull'):
|
||||
value = self.to_python_boolean(value)
|
||||
elif lookup.endswith('__in'):
|
||||
@ -106,7 +121,7 @@ class FieldLookupBackend(BaseFilterBackend):
|
||||
return value
|
||||
else:
|
||||
value = self.value_to_python_for_field(field, value)
|
||||
return value
|
||||
return value, new_lookup
|
||||
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
try:
|
||||
@ -152,13 +167,13 @@ class FieldLookupBackend(BaseFilterBackend):
|
||||
for value in values:
|
||||
if q_int:
|
||||
value = int(value)
|
||||
value = self.value_to_python(queryset.model, key, value)
|
||||
value, new_key = self.value_to_python(queryset.model, key, value)
|
||||
if q_chain:
|
||||
chain_filters.append((q_not, key, value))
|
||||
chain_filters.append((q_not, new_key, value))
|
||||
elif q_or:
|
||||
or_filters.append((q_not, key, value))
|
||||
or_filters.append((q_not, new_key, value))
|
||||
else:
|
||||
and_filters.append((q_not, key, value))
|
||||
and_filters.append((q_not, new_key, value))
|
||||
|
||||
# Now build Q objects for database query filter.
|
||||
if and_filters or or_filters or chain_filters:
|
||||
|
@ -168,7 +168,7 @@ class DashboardView(APIView):
|
||||
|
||||
user_groups = get_user_queryset(request.user, Group)
|
||||
groups_job_failed = (Group.objects.filter(hosts_with_active_failures__gt=0) | Group.objects.filter(groups_with_active_failures__gt=0)).count()
|
||||
groups_inventory_failed = Group.objects.filter(inventory_sources__last_update_failed=True).count()
|
||||
groups_inventory_failed = Group.objects.filter(inventory_sources__last_job_failed=True).count()
|
||||
data['groups'] = {'url': reverse('api:group_list'),
|
||||
'failures_url': reverse('api:group_list') + "?has_active_failures=True",
|
||||
'total': user_groups.count(),
|
||||
@ -183,32 +183,32 @@ class DashboardView(APIView):
|
||||
'failed': user_hosts_failed.count()}
|
||||
|
||||
user_projects = get_user_queryset(request.user, Project)
|
||||
user_projects_failed = user_projects.filter(last_update_failed=True)
|
||||
user_projects_failed = user_projects.filter(last_job_failed=True)
|
||||
data['projects'] = {'url': reverse('api:project_list'),
|
||||
'failures_url': reverse('api:project_list') + "?last_update_failed=True",
|
||||
'failures_url': reverse('api:project_list') + "?last_job_failed=True",
|
||||
'total': user_projects.count(),
|
||||
'failed': user_projects_failed.count()}
|
||||
|
||||
git_projects = user_projects.filter(scm_type='git')
|
||||
git_failed_projects = git_projects.filter(last_update_failed=True)
|
||||
git_failed_projects = git_projects.filter(last_job_failed=True)
|
||||
svn_projects = user_projects.filter(scm_type='svn')
|
||||
svn_failed_projects = svn_projects.filter(last_update_failed=True)
|
||||
svn_failed_projects = svn_projects.filter(last_job_failed=True)
|
||||
hg_projects = user_projects.filter(scm_type='hg')
|
||||
hg_failed_projects = hg_projects.filter(last_update_failed=True)
|
||||
hg_failed_projects = hg_projects.filter(last_job_failed=True)
|
||||
data['scm_types'] = {}
|
||||
data['scm_types']['git'] = {'url': reverse('api:project_list') + "?scm_type=git",
|
||||
'label': 'Git',
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=git&last_update_failed=True",
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=git&last_job_failed=True",
|
||||
'total': git_projects.count(),
|
||||
'failed': git_failed_projects.count()}
|
||||
data['scm_types']['svn'] = {'url': reverse('api:project_list') + "?scm_type=svn",
|
||||
'label': 'Subversion',
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=svn&last_update_failed=True",
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=svn&last_job_failed=True",
|
||||
'total': svn_projects.count(),
|
||||
'failed': svn_failed_projects.count()}
|
||||
data['scm_types']['hg'] = {'url': reverse('api:project_list') + "?scm_type=hg",
|
||||
'label': 'Mercurial',
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=hg&last_update_failed=True",
|
||||
'failures_url': reverse('api:project_list') + "?scm_type=hg&last_job_failed=True",
|
||||
'total': hg_projects.count(),
|
||||
'failed': hg_failed_projects.count()}
|
||||
|
||||
|
@ -183,6 +183,19 @@ class ProjectsTest(BaseTest):
|
||||
self.get(url, expect=401)
|
||||
self.get(url, expect=401, auth=self.get_invalid_credentials())
|
||||
|
||||
def test_dashboard(self):
|
||||
url = reverse('api:dashboard_view')
|
||||
# superuser can read dashboard.
|
||||
response = self.get(url, expect=200, auth=self.get_super_credentials())
|
||||
# org admin can read dashboard.
|
||||
response = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
# regular user can read dashboard.
|
||||
response = self.get(url, expect=200, auth=self.get_nobody_credentials())
|
||||
# anonymous/invalid user can't access dashboard.
|
||||
self.get(url, expect=401)
|
||||
self.get(url, expect=401, auth=self.get_invalid_credentials())
|
||||
# FIXME: Test that data on dashboard is filtered based on RBAC.
|
||||
|
||||
def test_mainline(self):
|
||||
|
||||
# =====================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user