• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TOMToolkit / tom_base / 6713509976

31 Oct 2023 11:13PM UTC coverage: 86.773% (+0.7%) from 86.072%
6713509976

push

github-actions

web-flow
Merge pull request #699 from TOMToolkit/dev

Multi-Feature Merge. Please Review Carefully.

795 of 795 new or added lines in 39 files covered. (100.0%)

8253 of 9511 relevant lines covered (86.77%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/tom_targets/api_views.py
1
from django_filters import rest_framework as drf_filters
1✔
2
from guardian.mixins import PermissionListMixin
1✔
3
from guardian.shortcuts import get_objects_for_user
1✔
4
from rest_framework.mixins import DestroyModelMixin, RetrieveModelMixin
1✔
5
from rest_framework.viewsets import GenericViewSet, ModelViewSet
1✔
6
from rest_framework import status
1✔
7

8
from tom_targets.filters import TargetFilter
1✔
9
from tom_targets.models import TargetExtra, TargetName, TargetList
1✔
10
from tom_targets.serializers import TargetSerializer, TargetExtraSerializer, TargetNameSerializer, TargetListSerializer
1✔
11

12

13
permissions_map = {  # TODO: Use the built-in DRF mapping or just switch to DRF entirely.
1✔
14
        'GET': 'view_target',
15
        'OPTIONS': [],
16
        'HEAD': [],
17
        'POST': 'add_target',
18
        'PATCH': 'change_target',
19
        'PUT': 'change_target',
20
        'DELETE': 'delete_target'
21
    }
22

23

24
# Though DRF supports using django-guardian as a permission backend without explicitly using PermissionListMixin, we
25
# chose to use it because it removes the requirement that a user be granted both object- and model-level permissions,
26
# and a user that has object-level permissions is understood to also have model-level permissions.
27
# For whatever reason, get_queryset has to be explicitly defined, and can't be set as a property, else the API won't
28
# respect permissions.
29
#
30
# At present, create is not restricted at all. This seems to be a limitation of django-guardian and should be revisited.
31
class TargetViewSet(ModelViewSet, PermissionListMixin):
1✔
32
    """
33
    Viewset for Target objects. By default supports CRUD operations.
34
    See the docs on viewsets: https://www.django-rest-framework.org/api-guide/viewsets/
35

36
    To view supported query parameters, please use the ``OPTIONS`` endpoint, which can be accessed through the web UI.
37

38
    **Please note that ``groups`` are an accepted query parameters for the ``CREATE`` endpoint. The ``groups`` parameter
39
    will specify which ``groups`` can view the created Target. If no ``groups`` are specified, the ``Target`` will only
40
    be visible to the user that created the ``Target``. Make sure to check your ``groups``!!**
41

42
    In order to create new ``TargetName`` or ``TargetExtra`` objects, a dictionary with the new values must be appended
43
    to the ``aliases`` or ``targetextra_set`` lists. If ``id`` is included, the API will attempt to update an existing
44
    ``TargetName`` or ``TargetExtra``. If no ``id`` is provided, the API will attempt to create new entries.
45

46
    ``TargetName`` and ``TargetExtra`` objects can only be deleted or specifically retrieved via the
47
    ``/api/targetname/`` or ``/api/targetextra/`` endpoints.
48
    """
49
    serializer_class = TargetSerializer
1✔
50
    filter_backends = (drf_filters.DjangoFilterBackend,)
1✔
51
    filterset_class = TargetFilter
1✔
52

53
    def get_queryset(self):
1✔
54
        permission_required = permissions_map.get(self.request.method)
1✔
55
        return get_objects_for_user(self.request.user, f'tom_targets.{permission_required}')
1✔
56

57
    def create(self, request, *args, **kwargs):
1✔
58
        response = super().create(request, *args, **kwargs)
1✔
59

60
        # Custom message for successful target creation
61
        if response.status_code == status.HTTP_201_CREATED:
1✔
62
            response.data['message'] = 'Target successfully uploaded.'
1✔
63
        return response
1✔
64

65
    def update(self, request, *args, **kwargs):
1✔
66
        response = super().update(request, *args, **kwargs)
1✔
67

68
        # Custom message for successful target update
69
        if response.status_code == status.HTTP_200_OK:
1✔
70
            response.data['message'] = 'Target successfully updated.'
1✔
71
        return response
1✔
72

73

74
class TargetNameViewSet(DestroyModelMixin, PermissionListMixin, RetrieveModelMixin, GenericViewSet):
1✔
75
    """
76
    Viewset for TargetName objects. Only ``GET`` and ``DELETE`` operations are permitted.
77

78
    To view available query parameters, please use the OPTIONS endpoint, which can be accessed through the web UI.
79
    """
80
    serializer_class = TargetNameSerializer
1✔
81

82
    def get_queryset(self):
1✔
83
        permission_required = permissions_map.get(self.request.method)
1✔
84
        return TargetName.objects.filter(
1✔
85
            target__in=get_objects_for_user(self.request.user, f'tom_targets.{permission_required}')
86
        )
87

88

89
class TargetExtraViewSet(DestroyModelMixin, PermissionListMixin, RetrieveModelMixin, GenericViewSet):
1✔
90
    """
91
    Viewset for TargetExtra objects. Only ``GET`` and ``DELETE`` operations are permitted.
92

93
    To view available query parameters, please use the OPTIONS endpoint, which can be accessed through the web UI.
94
    """
95
    serializer_class = TargetExtraSerializer
1✔
96

97
    def get_queryset(self):
1✔
98
        permission_required = permissions_map.get(self.request.method)
1✔
99
        return TargetExtra.objects.filter(
1✔
100
            target__in=get_objects_for_user(self.request.user, f'tom_targets.{permission_required}')
101
        )
102

103

104
class TargetListViewSet(DestroyModelMixin, PermissionListMixin, RetrieveModelMixin, GenericViewSet):
1✔
105
    """
106
    Viewset for TargetList objects. Only ``GET`` and ``DELETE`` operations are permitted.
107

108
    To view available query parameters, please use the OPTIONS endpoint, which can be accessed through the web UI.
109
    """
110
    serializer_class = TargetListSerializer
1✔
111

112
    def get_queryset(self):
1✔
113
        permission_required = permissions_map.get(self.request.method)
×
114
        return TargetList.objects.filter(
×
115
            target__in=get_objects_for_user(self.request.user, f'tom_targets.{permission_required}')
116
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc