diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 76088bf3c..ec72910c9 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -1,7 +1,9 @@ from rest_framework import serializers from dcim.api.serializers import NestedSiteSerializer -from extras.models import Graph, TopologyMap +from extras.models import ACTION_CHOICES, Graph, TopologyMap, UserAction +from users.api.serializers import NestedUserSerializer +from utilities.api import ChoiceFieldSerializer # @@ -40,3 +42,16 @@ class WritableTopologyMapSerializer(serializers.ModelSerializer): class Meta: model = TopologyMap fields = ['name', 'slug', 'site', 'device_patterns', 'description'] + + +# +# User actions +# + +class UserActionSerializer(serializers.ModelSerializer): + user = NestedUserSerializer() + action = ChoiceFieldSerializer(choices=ACTION_CHOICES) + + class Meta: + model = UserAction + fields = ['id', 'time', 'user', 'action', 'message'] diff --git a/netbox/extras/api/urls.py b/netbox/extras/api/urls.py index 2ca80ea37..141b4b7e4 100644 --- a/netbox/extras/api/urls.py +++ b/netbox/extras/api/urls.py @@ -8,4 +8,7 @@ router = routers.DefaultRouter() # Topology maps router.register(r'topology-maps', views.TopologyMapViewSet) +# Recent activity +router.register(r'recent-activity', views.RecentActivityViewSet) + urlpatterns = router.urls diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 20e2901f7..9047fd403 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -1,6 +1,6 @@ from rest_framework import generics from rest_framework.decorators import detail_route -from rest_framework.viewsets import ModelViewSet +from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from django.contrib.contenttypes.models import ContentType from django.http import Http404, HttpResponse @@ -9,14 +9,14 @@ from django.shortcuts import get_object_or_404 from circuits.models import Provider from dcim.models import Site, Interface from extras import filters -from extras.models import Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_PROVIDER, GRAPH_TYPE_SITE +from extras.models import Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_PROVIDER, GRAPH_TYPE_SITE, UserAction from utilities.api import WritableSerializerMixin from . import serializers class CustomFieldModelViewSet(ModelViewSet): """ - Include the applicable set of CustomField in the ModelViewSet context. + Include the applicable set of CustomFields in the ModelViewSet context. """ def get_serializer_context(self): @@ -95,3 +95,12 @@ class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet): response['Content-Disposition'] = 'inline; filename="{}.{}"'.format(tmap.slug, img_format) return response + + +class RecentActivityViewSet(ReadOnlyModelViewSet): + """ + List all UserActions to provide a log of recent activity. + """ + queryset = UserAction.objects.all() + serializer_class = serializers.UserActionSerializer + filter_class = filters.UserActionFilter diff --git a/netbox/extras/filters.py b/netbox/extras/filters.py index 98f1a5a1e..609a0789a 100644 --- a/netbox/extras/filters.py +++ b/netbox/extras/filters.py @@ -1,9 +1,10 @@ import django_filters +from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from dcim.models import Site -from .models import CF_TYPE_SELECT, CustomField, TopologyMap +from .models import CF_TYPE_SELECT, CustomField, TopologyMap, UserAction class CustomFieldFilter(django_filters.Filter): @@ -63,3 +64,15 @@ class TopologyMapFilter(django_filters.FilterSet): class Meta: model = TopologyMap fields = ['name', 'slug'] + + +class UserActionFilter(django_filters.FilterSet): + username = django_filters.ModelMultipleChoiceFilter( + name='user__username', + queryset=User.objects.all(), + to_field_name='username', + ) + + class Meta: + model = UserAction + fields = ['user'] diff --git a/netbox/users/api/__init__.py b/netbox/users/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/netbox/users/api/serializers.py b/netbox/users/api/serializers.py new file mode 100644 index 000000000..893a989bc --- /dev/null +++ b/netbox/users/api/serializers.py @@ -0,0 +1,10 @@ +from django.contrib.auth.models import User + +from rest_framework import serializers + + +class NestedUserSerializer(serializers.ModelSerializer): + + class Meta: + model = User + fields = ['id', 'username']