diff --git a/netbox/templates/users/group.html b/netbox/templates/users/group.html
new file mode 100644
index 000000000..ec5c0acad
--- /dev/null
+++ b/netbox/templates/users/group.html
@@ -0,0 +1,43 @@
+{% extends 'users/base.html' %}
+{% load helpers %}
+{% load render_table from django_tables2 %}
+
+{% block title %}Group Detail{% endblock %}
+
+{% block tabs %}
+
+{% endblock tabs %}
+
+{% block content %}
+
+
+
+
+
+
+
+ Name |
+ {{ object.name }} |
+
+
+
+
+
+
+
+
+
+ {% for group in request.user.groups.all %}
+ - {{ group }}
+ {% empty %}
+ - None
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/netbox/templates/users/objectpermission.html b/netbox/templates/users/objectpermission.html
new file mode 100644
index 000000000..4fdbb428a
--- /dev/null
+++ b/netbox/templates/users/objectpermission.html
@@ -0,0 +1,43 @@
+{% extends 'users/base.html' %}
+{% load helpers %}
+{% load render_table from django_tables2 %}
+
+{% block title %}Permission Detail{% endblock %}
+
+{% block tabs %}
+
+{% endblock tabs %}
+
+{% block content %}
+
+
+
+
+
+
+
+ Name |
+ {{ object.name }} |
+
+
+
+
+
+
+
+
+
+ {% for group in request.user.groups.all %}
+ - {{ group }}
+ {% empty %}
+ - None
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/netbox/templates/users/user.html b/netbox/templates/users/user.html
new file mode 100644
index 000000000..3b514b103
--- /dev/null
+++ b/netbox/templates/users/user.html
@@ -0,0 +1,81 @@
+{% extends 'users/base.html' %}
+{% load helpers %}
+{% load render_table from django_tables2 %}
+
+{% block title %}User Detail{% endblock %}
+
+{% block tabs %}
+
+{% endblock tabs %}
+
+{% block content %}
+
+
+
+
+
+
+
+ Username |
+ {{ object.username }} |
+
+
+ Full Name |
+
+ {% if object.first_name or object.last_name %}
+ {{ object.first_name }} {{ object.last_name }}
+ {% else %}
+ {{ ''|placeholder }}
+ {% endif %}
+ |
+
+
+ Email |
+ {{ object.email|placeholder }} |
+
+
+ Account Created |
+ {{ object.date_joined|annotated_date }} |
+
+
+ Superuser |
+ {% checkmark object.is_superuser %} |
+
+
+ Admin Access |
+ {% checkmark object.is_staff %} |
+
+
+
+
+
+
+
+
+
+ {% for group in object.groups.all %}
+ - {{ group }}
+ {% empty %}
+ - None
+ {% endfor %}
+
+
+
+
+ {% if perms.extras.view_objectchange %}
+
+
+
+
+
+ {% render_table changelog_table 'inc/table.html' %}
+
+
+
+
+ {% endif %}
+{% endblock %}
diff --git a/netbox/users/filtersets.py b/netbox/users/filtersets.py
index 35353b4a3..e89f35830 100644
--- a/netbox/users/filtersets.py
+++ b/netbox/users/filtersets.py
@@ -49,7 +49,7 @@ class UserFilterSet(BaseFilterSet):
)
class Meta:
- model = NetBoxUser
+ model = get_user_model()
fields = ['id', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active']
def search(self, queryset, name, value):
diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py
index ea5869654..20f779bf2 100644
--- a/netbox/users/forms/model_forms.py
+++ b/netbox/users/forms/model_forms.py
@@ -146,34 +146,52 @@ class TokenForm(BootstrapMixin, forms.ModelForm):
class UserForm(BootstrapMixin, forms.ModelForm):
groups = DynamicModelMultipleChoiceField(
+ required=False,
queryset=Group.objects.all()
)
+ object_permissions = DynamicModelMultipleChoiceField(
+ required=False,
+ label=_('Permissions'),
+ queryset=ObjectPermission.objects.all()
+ )
fieldsets = (
('User', ('username', 'first_name', 'last_name', 'email', )),
('Groups', ('groups', )),
('Status', ('is_active', 'is_staff', 'is_superuser', )),
('Important Dates', ('last_login', 'date_joined', )),
+ ('Permissions', ('object_permissions', )),
)
class Meta:
model = NetBoxUser
fields = [
- 'username', 'first_name', 'last_name', 'email', 'groups',
+ 'username', 'first_name', 'last_name', 'email', 'groups', 'object_permissions',
'is_active', 'is_staff', 'is_superuser', 'last_login', 'date_joined',
]
class GroupForm(BootstrapMixin, forms.ModelForm):
+ users = DynamicModelMultipleChoiceField(
+ required=False,
+ queryset=get_user_model().objects.all()
+ )
+ object_permissions = DynamicModelMultipleChoiceField(
+ required=False,
+ label=_('Permissions'),
+ queryset=ObjectPermission.objects.all()
+ )
fieldsets = (
- ('name', ),
+ ('', ('name', )),
+ ('Users', ('users', )),
+ ('Permissions', ('object_permissions', )),
)
class Meta:
model = NetBoxGroup
fields = [
- 'name',
+ 'name', 'users', 'object_permissions',
]
diff --git a/netbox/users/tables.py b/netbox/users/tables.py
index 4931d9327..cc181763f 100644
--- a/netbox/users/tables.py
+++ b/netbox/users/tables.py
@@ -2,7 +2,7 @@ import django_tables2 as tables
from django_tables2.utils import A
from .models import Token
from netbox.tables import NetBoxTable, columns
-from users.models import NetBoxUser
+from users.models import NetBoxGroup, NetBoxUser
__all__ = (
'GroupTable',
@@ -73,21 +73,21 @@ class UserTable(NetBoxTable):
class GroupTable(NetBoxTable):
- username = tables.LinkColumn('users:netboxuser', args=[A('pk')])
+ name = tables.LinkColumn('users:netboxgroup', args=[A('pk')])
actions = columns.ActionsColumn(
actions=('edit', 'delete'),
)
class Meta(NetBoxTable.Meta):
- model = NetBoxUser
+ model = NetBoxGroup
fields = (
- 'pk', 'id', 'username', 'email', 'first_name', 'last_name', 'is_superuser', 'is_staff', 'is_active'
+ 'pk', 'id', 'name', 'users_count',
)
- default_columns = ('pk', 'username', 'email', 'first_name', 'last_name', 'is_superuser')
+ default_columns = ('pk', 'name', 'users_count', )
class ObjectPermissionTable(NetBoxTable):
- username = tables.LinkColumn('users:netboxuser', args=[A('pk')])
+ name = tables.LinkColumn('users:objectpermission', args=[A('pk')])
actions = columns.ActionsColumn(
actions=('edit', 'delete'),
)
@@ -95,6 +95,6 @@ class ObjectPermissionTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = NetBoxUser
fields = (
- 'pk', 'id', 'username', 'email', 'first_name', 'last_name', 'is_superuser', 'is_staff', 'is_active'
+ 'pk', 'id', 'name', 'enabled', 'actions', 'constraints',
)
- default_columns = ('pk', 'username', 'email', 'first_name', 'last_name', 'is_superuser')
+ default_columns = ('pk', 'name', 'enabled', 'actions', 'constraints',)
diff --git a/netbox/users/views.py b/netbox/users/views.py
index 3bf6d5e1c..012b30453 100644
--- a/netbox/users/views.py
+++ b/netbox/users/views.py
@@ -6,6 +6,7 @@ from django.contrib.auth import login as auth_login, logout as auth_logout, upda
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import update_last_login
from django.contrib.auth.signals import user_logged_in
+from django.db.models import Count
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render, resolve_url
from django.urls import reverse
@@ -398,7 +399,7 @@ class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
class NetBoxGroupListView(generic.ObjectListView):
- queryset = NetBoxGroup.objects.all()
+ queryset = NetBoxGroup.objects.all().annotate(users_count=Count('user'))
filterset = filtersets.GroupFilterSet
filterset_form = forms.GroupFilterForm
table = tables.GroupTable
@@ -409,6 +410,11 @@ class NetBoxGroupView(generic.ObjectView):
queryset = NetBoxGroup.objects.all()
template_name = 'users/group.html'
+ def get_extra_context(self, request, instance):
+ return {
+ 'active_tab': 'group',
+ }
+
@register_model_view(NetBoxGroup, 'edit')
class NetBoxGroupEditView(generic.ObjectEditView):
@@ -455,6 +461,11 @@ class ObjectPermissionView(generic.ObjectView):
queryset = NetBoxGroup.objects.all()
template_name = 'users/objectpermission.html'
+ def get_extra_context(self, request, instance):
+ return {
+ 'active_tab': 'objectpermission',
+ }
+
@register_model_view(ObjectPermission, 'edit')
class ObjectPermissionEditView(generic.ObjectEditView):