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 %} +
+
+
+
Account Details
+
+ + + + + +
Name{{ object.name }}
+
+
+
+
+
+
Assigned Groups
+
    + {% 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 %} +
+
+
+
Account Details
+
+ + + + + +
Name{{ object.name }}
+
+
+
+
+
+
Assigned Groups
+
    + {% 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 %} +
+
+
+
Account Details
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
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 %}
+
+
+
+
+
+
Assigned Groups
+
    + {% for group in object.groups.all %} +
  • {{ group }}
  • + {% empty %} +
  • None
  • + {% endfor %} +
+
+
+
+ {% if perms.extras.view_objectchange %} +
+
+
+
Recent Activity
+
+ {% 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):