mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
commit
c507ab30e9
@ -1,5 +1,13 @@
|
|||||||
# NetBox v2.8
|
# NetBox v2.8
|
||||||
|
|
||||||
|
## v2.8.3 (2020-05-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* [#4593](https://github.com/netbox-community/netbox/issues/4593) - Fix AttributeError exception when viewing object lists as a non-authenticated user
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v2.8.2 (2020-05-06)
|
## v2.8.2 (2020-05-06)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
@ -124,9 +124,12 @@ class ConfigContextView(PermissionRequiredMixin, View):
|
|||||||
# Determine user's preferred output format
|
# Determine user's preferred output format
|
||||||
if request.GET.get('format') in ['json', 'yaml']:
|
if request.GET.get('format') in ['json', 'yaml']:
|
||||||
format = request.GET.get('format')
|
format = request.GET.get('format')
|
||||||
request.user.config.set('extras.configcontext.format', format, commit=True)
|
if request.user.is_authenticated:
|
||||||
else:
|
request.user.config.set('extras.configcontext.format', format, commit=True)
|
||||||
|
elif request.user.is_authenticated:
|
||||||
format = request.user.config.get('extras.configcontext.format', 'json')
|
format = request.user.config.get('extras.configcontext.format', 'json')
|
||||||
|
else:
|
||||||
|
format = 'json'
|
||||||
|
|
||||||
return render(request, 'extras/configcontext.html', {
|
return render(request, 'extras/configcontext.html', {
|
||||||
'configcontext': configcontext,
|
'configcontext': configcontext,
|
||||||
@ -181,9 +184,12 @@ class ObjectConfigContextView(View):
|
|||||||
# Determine user's preferred output format
|
# Determine user's preferred output format
|
||||||
if request.GET.get('format') in ['json', 'yaml']:
|
if request.GET.get('format') in ['json', 'yaml']:
|
||||||
format = request.GET.get('format')
|
format = request.GET.get('format')
|
||||||
request.user.config.set('extras.configcontext.format', format, commit=True)
|
if request.user.is_authenticated:
|
||||||
else:
|
request.user.config.set('extras.configcontext.format', format, commit=True)
|
||||||
|
elif request.user.is_authenticated:
|
||||||
format = request.user.config.get('extras.configcontext.format', 'json')
|
format = request.user.config.get('extras.configcontext.format', 'json')
|
||||||
|
else:
|
||||||
|
format = 'json'
|
||||||
|
|
||||||
return render(request, 'extras/object_configcontext.html', {
|
return render(request, 'extras/object_configcontext.html', {
|
||||||
model_name: obj,
|
model_name: obj,
|
||||||
|
@ -16,7 +16,7 @@ from django.core.validators import URLValidator
|
|||||||
# Environment setup
|
# Environment setup
|
||||||
#
|
#
|
||||||
|
|
||||||
VERSION = '2.8.2'
|
VERSION = '2.8.3'
|
||||||
|
|
||||||
# Hostname
|
# Hostname
|
||||||
HOSTNAME = platform.node()
|
HOSTNAME = platform.node()
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="pull-right noprint">
|
<div class="pull-right noprint">
|
||||||
{% block buttons %}{% endblock %}
|
{% block buttons %}{% endblock %}
|
||||||
{% if table_config_form %}
|
{% if request.user.is_authenticated and table_config_form %}
|
||||||
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#tableconfig" title="Configure table"><i class="fa fa-cog"></i> Configure</button>
|
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#tableconfig" title="Configure table"><i class="fa fa-cog"></i> Configure</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if permissions.add and 'add' in action_buttons %}
|
{% if permissions.add and 'add' in action_buttons %}
|
||||||
|
@ -50,9 +50,12 @@ def get_paginate_count(request):
|
|||||||
if 'per_page' in request.GET:
|
if 'per_page' in request.GET:
|
||||||
try:
|
try:
|
||||||
per_page = int(request.GET.get('per_page'))
|
per_page = int(request.GET.get('per_page'))
|
||||||
request.user.config.set('pagination.per_page', per_page, commit=True)
|
if request.user.is_authenticated:
|
||||||
|
request.user.config.set('pagination.per_page', per_page, commit=True)
|
||||||
return per_page
|
return per_page
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return request.user.config.get('pagination.per_page', settings.PAGINATE_COUNT)
|
if request.user.is_authenticated:
|
||||||
|
return request.user.config.get('pagination.per_page', settings.PAGINATE_COUNT)
|
||||||
|
return settings.PAGINATE_COUNT
|
||||||
|
@ -164,6 +164,13 @@ class ViewTestCases:
|
|||||||
response = self.client.get(instance.get_absolute_url())
|
response = self.client.get(instance.get_absolute_url())
|
||||||
self.assertHttpStatus(response, 200)
|
self.assertHttpStatus(response, 200)
|
||||||
|
|
||||||
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
|
||||||
|
def test_list_objects_anonymous(self):
|
||||||
|
# Make the request as an unauthenticated user
|
||||||
|
self.client.logout()
|
||||||
|
response = self.client.get(self.model.objects.first().get_absolute_url())
|
||||||
|
self.assertHttpStatus(response, 200)
|
||||||
|
|
||||||
class CreateObjectViewTestCase(ModelViewTestCase):
|
class CreateObjectViewTestCase(ModelViewTestCase):
|
||||||
"""
|
"""
|
||||||
Create a single new instance.
|
Create a single new instance.
|
||||||
@ -287,6 +294,13 @@ class ViewTestCases:
|
|||||||
self.assertHttpStatus(response, 200)
|
self.assertHttpStatus(response, 200)
|
||||||
self.assertEqual(response.get('Content-Type'), 'text/csv')
|
self.assertEqual(response.get('Content-Type'), 'text/csv')
|
||||||
|
|
||||||
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
|
||||||
|
def test_list_objects_anonymous(self):
|
||||||
|
# Make the request as an unauthenticated user
|
||||||
|
self.client.logout()
|
||||||
|
response = self.client.get(self._get_url('list'))
|
||||||
|
self.assertHttpStatus(response, 200)
|
||||||
|
|
||||||
class BulkCreateObjectsViewTestCase(ModelViewTestCase):
|
class BulkCreateObjectsViewTestCase(ModelViewTestCase):
|
||||||
"""
|
"""
|
||||||
Create multiple instances using a single form. Expects the creation of three new instances by default.
|
Create multiple instances using a single form. Expects the creation of three new instances by default.
|
||||||
|
@ -3,6 +3,7 @@ import sys
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import FieldDoesNotExist, ValidationError
|
from django.core.exceptions import FieldDoesNotExist, ValidationError
|
||||||
from django.db import transaction, IntegrityError
|
from django.db import transaction, IntegrityError
|
||||||
@ -13,6 +14,7 @@ from django.shortcuts import get_object_or_404, redirect, render
|
|||||||
from django.template import loader
|
from django.template import loader
|
||||||
from django.template.exceptions import TemplateDoesNotExist
|
from django.template.exceptions import TemplateDoesNotExist
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.http import is_safe_url
|
from django.utils.http import is_safe_url
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
@ -164,7 +166,10 @@ class ObjectListView(View):
|
|||||||
permissions[action] = request.user.has_perm(perm_name)
|
permissions[action] = request.user.has_perm(perm_name)
|
||||||
|
|
||||||
# Construct the table based on the user's permissions
|
# Construct the table based on the user's permissions
|
||||||
columns = request.user.config.get(f"tables.{self.table.__name__}.columns")
|
if request.user.is_authenticated:
|
||||||
|
columns = request.user.config.get(f"tables.{self.table.__name__}.columns")
|
||||||
|
else:
|
||||||
|
columns = None
|
||||||
table = self.table(self.queryset, columns=columns)
|
table = self.table(self.queryset, columns=columns)
|
||||||
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
||||||
table.columns.show('pk')
|
table.columns.show('pk')
|
||||||
@ -188,6 +193,7 @@ class ObjectListView(View):
|
|||||||
|
|
||||||
return render(request, self.template_name, context)
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
|
||||||
# Update the user's table configuration
|
# Update the user's table configuration
|
||||||
|
Loading…
Reference in New Issue
Block a user