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

TOMToolkit / tom_base / 6488803620

11 Oct 2023 10:42PM UTC coverage: 87.097% (+0.03%) from 87.07%
6488803620

Pull #676

github-actions

jchate6
Merge branch 'feature/tom2tom_data_sharing' into feature/tom-tom-target-sharing
Pull Request #676: Feature/tom tom target sharing

376 of 376 new or added lines in 14 files covered. (100.0%)

8181 of 9393 relevant lines covered (87.1%)

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
        if response.status_code == status.HTTP_201_CREATED:
1✔
61
            response.data['message'] = 'Target successfully uploaded.'
1✔
62
        return response
1✔
63

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

67
        if response.status_code == status.HTTP_200_OK:
1✔
68
            response.data['message'] = 'Target successfully updated.'
1✔
69
        return response
1✔
70

71

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

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

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

86

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

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

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

101

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

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

110
    def get_queryset(self):
1✔
111
        permission_required = permissions_map.get(self.request.method)
×
112
        return TargetList.objects.filter(
×
113
            target__in=get_objects_for_user(self.request.user, f'tom_targets.{permission_required}')
114
        )
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