From 36dc0d7059056164b691f126855ccd7715c5730a Mon Sep 17 00:00:00 2001 From: Chris Church Date: Fri, 2 Dec 2016 16:54:24 -0500 Subject: [PATCH 1/2] Add workflows as a licensed feature, add mixin for workflow and activity stream license enforcement on views, update mixins to consistently come before base classes. --- awx/api/generics.py | 4 +- awx/api/views.py | 303 ++++++++++++-------------------------------- 2 files changed, 83 insertions(+), 224 deletions(-) diff --git a/awx/api/generics.py b/awx/api/generics.py index 0c593925c0..1062135a28 100644 --- a/awx/api/generics.py +++ b/awx/api/generics.py @@ -296,7 +296,7 @@ class ParentMixin(object): raise PermissionDenied() -class SubListAPIView(ListAPIView, ParentMixin): +class SubListAPIView(ParentMixin, ListAPIView): # Base class for a read-only sublist view. # Subclasses should define at least: @@ -501,7 +501,7 @@ class DeleteLastUnattachLabelMixin(object): return res -class SubDetailAPIView(generics.RetrieveAPIView, GenericAPIView, ParentMixin): +class SubDetailAPIView(ParentMixin, generics.RetrieveAPIView, GenericAPIView): pass diff --git a/awx/api/views.py b/awx/api/views.py index f0d1d3fc75..c656887dd9 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -88,6 +88,36 @@ def api_exception_handler(exc, context): return exception_handler(exc, context) +class ActivityStreamEnforcementMixin(object): + ''' + Mixin to check that license supports activity streams. + ''' + def check_permissions(self, request): + if not feature_enabled('activity_streams'): + raise LicenseForbids(_('Your license does not allow use of the activity stream.')) + return super(ActivityStreamEnforcementMixin, self).check_permissions(request) + + +class SystemTrackingEnforcementMixin(object): + ''' + Mixin to check that license supports system tracking. + ''' + def check_permissions(self, request): + if not feature_enabled('system_tracking'): + raise LicenseForbids(_('Your license does not permit use of system tracking.')) + return super(SystemTrackingEnforcementMixin, self).check_permissions(request) + + +class WorkflowsEnforcementMixin(object): + ''' + Mixin to check that license supports workflows. + ''' + def check_permissions(self, request): + if not feature_enabled('workflows'): + raise LicenseForbids(_('Your license does not allow use of workflows.')) + return super(WorkflowsEnforcementMixin, self).check_permissions(request) + + class ApiRootView(APIView): authentication_classes = [] @@ -788,7 +818,7 @@ class OrganizationTeamsList(SubListCreateAttachDetachAPIView): parent_key = 'organization' -class OrganizationActivityStreamList(SubListAPIView): +class OrganizationActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -796,16 +826,6 @@ class OrganizationActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(OrganizationActivityStreamList, self).get(request, *args, **kwargs) - class OrganizationNotificationTemplatesList(SubListCreateAttachDetachAPIView): @@ -953,7 +973,7 @@ class TeamProjectsList(SubListAPIView): return self.model.accessible_objects(self.request.user, 'read_role').filter(pk__in=[t.content_object.pk for t in proj_roles]) -class TeamActivityStreamList(SubListAPIView): +class TeamActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -961,16 +981,6 @@ class TeamActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(TeamActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -1054,7 +1064,7 @@ class ProjectSchedulesList(SubListCreateAttachDetachAPIView): new_in_148 = True -class ProjectActivityStreamList(SubListAPIView): +class ProjectActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1062,16 +1072,6 @@ class ProjectActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(ProjectActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -1341,7 +1341,7 @@ class UserAdminOfOrganizationsList(OrganizationCountsMixin, SubListAPIView): return my_qs & user_qs -class UserActivityStreamList(SubListAPIView): +class UserActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1349,16 +1349,6 @@ class UserActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(UserActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -1502,7 +1492,7 @@ class CredentialDetail(RetrieveUpdateDestroyAPIView): serializer_class = CredentialSerializer -class CredentialActivityStreamList(SubListAPIView): +class CredentialActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1510,16 +1500,6 @@ class CredentialActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(CredentialActivityStreamList, self).get(request, *args, **kwargs) - class CredentialAccessList(ResourceAccessList): @@ -1599,7 +1579,7 @@ class InventoryDetail(RetrieveUpdateDestroyAPIView): return super(InventoryDetail, self).destroy(request, *args, **kwargs) -class InventoryActivityStreamList(SubListAPIView): +class InventoryActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1607,16 +1587,6 @@ class InventoryActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(InventoryActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -1743,7 +1713,7 @@ class HostInventorySourcesList(SubListAPIView): new_in_148 = True -class HostActivityStreamList(SubListAPIView): +class HostActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1751,16 +1721,6 @@ class HostActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(HostActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -1768,18 +1728,7 @@ class HostActivityStreamList(SubListAPIView): return qs.filter(Q(host=parent) | Q(inventory=parent.inventory)) -class SystemTrackingEnforcementMixin(APIView): - ''' - Use check_permissions instead of initial() because it's in the OPTION's path as well - ''' - def check_permissions(self, request): - if not feature_enabled("system_tracking"): - raise LicenseForbids(_("Your license does not permit use " - "of system tracking.")) - return super(SystemTrackingEnforcementMixin, self).check_permissions(request) - - -class HostFactVersionsList(ListAPIView, ParentMixin, SystemTrackingEnforcementMixin): +class HostFactVersionsList(SystemTrackingEnforcementMixin, ParentMixin, ListAPIView): model = Fact serializer_class = FactVersionSerializer @@ -1805,7 +1754,7 @@ class HostFactVersionsList(ListAPIView, ParentMixin, SystemTrackingEnforcementMi return Response(dict(results=self.serializer_class(queryset, many=True).data)) -class HostFactCompareView(SubDetailAPIView, SystemTrackingEnforcementMixin): +class HostFactCompareView(SystemTrackingEnforcementMixin, SubDetailAPIView): model = Fact new_in_220 = True @@ -1939,7 +1888,7 @@ class GroupInventorySourcesList(SubListAPIView): new_in_148 = True -class GroupActivityStreamList(SubListAPIView): +class GroupActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -1947,16 +1896,6 @@ class GroupActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(GroupActivityStreamList, self).get(request, *args, **kwargs) - def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) @@ -2197,7 +2136,7 @@ class InventorySourceSchedulesList(SubListCreateAttachDetachAPIView): new_in_148 = True -class InventorySourceActivityStreamList(SubListAPIView): +class InventorySourceActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -2205,16 +2144,6 @@ class InventorySourceActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(InventorySourceActivityStreamList, self).get(request, *args, **kwargs) - class InventorySourceNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): @@ -2507,13 +2436,13 @@ class JobTemplateSurveySpec(GenericAPIView): return Response() -class WorkflowJobTemplateSurveySpec(JobTemplateSurveySpec): +class WorkflowJobTemplateSurveySpec(WorkflowsEnforcementMixin, JobTemplateSurveySpec): model = WorkflowJobTemplate parent_model = WorkflowJobTemplate -class JobTemplateActivityStreamList(SubListAPIView): +class JobTemplateActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -2521,16 +2450,6 @@ class JobTemplateActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(JobTemplateActivityStreamList, self).get(request, *args, **kwargs) - class JobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): @@ -2764,28 +2683,28 @@ class JobTemplateObjectRolesList(SubListAPIView): return Role.objects.filter(content_type=content_type, object_id=po.pk) -class WorkflowJobNodeList(ListAPIView): +class WorkflowJobNodeList(WorkflowsEnforcementMixin, ListAPIView): model = WorkflowJobNode serializer_class = WorkflowJobNodeListSerializer new_in_310 = True -class WorkflowJobNodeDetail(RetrieveAPIView): +class WorkflowJobNodeDetail(WorkflowsEnforcementMixin, RetrieveAPIView): model = WorkflowJobNode serializer_class = WorkflowJobNodeDetailSerializer new_in_310 = True -class WorkflowJobTemplateNodeList(ListCreateAPIView): +class WorkflowJobTemplateNodeList(WorkflowsEnforcementMixin, ListCreateAPIView): model = WorkflowJobTemplateNode serializer_class = WorkflowJobTemplateNodeListSerializer new_in_310 = True -class WorkflowJobTemplateNodeDetail(RetrieveUpdateDestroyAPIView): +class WorkflowJobTemplateNodeDetail(WorkflowsEnforcementMixin, RetrieveUpdateDestroyAPIView): model = WorkflowJobTemplateNode serializer_class = WorkflowJobTemplateNodeDetailSerializer @@ -2802,7 +2721,7 @@ class WorkflowJobTemplateNodeDetail(RetrieveUpdateDestroyAPIView): return super(WorkflowJobTemplateNodeDetail, self).update_raw_data(data) -class WorkflowJobTemplateNodeChildrenBaseList(EnforceParentRelationshipMixin, SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNodeChildrenBaseList(WorkflowsEnforcementMixin, EnforceParentRelationshipMixin, SubListCreateAttachDetachAPIView): model = WorkflowJobTemplateNode serializer_class = WorkflowJobTemplateNodeListSerializer @@ -2862,19 +2781,19 @@ class WorkflowJobTemplateNodeChildrenBaseList(EnforceParentRelationshipMixin, Su return None -class WorkflowJobTemplateNodeSuccessNodesList(WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeSuccessNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): relationship = 'success_nodes' -class WorkflowJobTemplateNodeFailureNodesList(WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeFailureNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): relationship = 'failure_nodes' -class WorkflowJobTemplateNodeAlwaysNodesList(WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeAlwaysNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): relationship = 'always_nodes' -class WorkflowJobNodeChildrenBaseList(SubListAPIView): +class WorkflowJobNodeChildrenBaseList(WorkflowsEnforcementMixin, SubListAPIView): model = WorkflowJobNode serializer_class = WorkflowJobNodeListSerializer @@ -2892,20 +2811,20 @@ class WorkflowJobNodeChildrenBaseList(SubListAPIView): return getattr(parent, self.relationship).all() -class WorkflowJobNodeSuccessNodesList(WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeSuccessNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): relationship = 'success_nodes' -class WorkflowJobNodeFailureNodesList(WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeFailureNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): relationship = 'failure_nodes' -class WorkflowJobNodeAlwaysNodesList(WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeAlwaysNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): relationship = 'always_nodes' # TODO: -class WorkflowJobTemplateList(ListCreateAPIView): +class WorkflowJobTemplateList(WorkflowsEnforcementMixin, ListCreateAPIView): model = WorkflowJobTemplate serializer_class = WorkflowJobTemplateListSerializer @@ -2924,7 +2843,7 @@ class WorkflowJobTemplateList(ListCreateAPIView): # TODO: -class WorkflowJobTemplateDetail(RetrieveUpdateDestroyAPIView): +class WorkflowJobTemplateDetail(WorkflowsEnforcementMixin, RetrieveUpdateDestroyAPIView): model = WorkflowJobTemplate serializer_class = WorkflowJobTemplateSerializer @@ -2932,7 +2851,7 @@ class WorkflowJobTemplateDetail(RetrieveUpdateDestroyAPIView): new_in_310 = True -class WorkflowJobTemplateCopy(GenericAPIView): +class WorkflowJobTemplateCopy(WorkflowsEnforcementMixin, GenericAPIView): model = WorkflowJobTemplate parent_model = WorkflowJobTemplate @@ -2958,12 +2877,12 @@ class WorkflowJobTemplateCopy(GenericAPIView): return Response(data, status=status.HTTP_201_CREATED) -class WorkflowJobTemplateLabelList(JobTemplateLabelList): +class WorkflowJobTemplateLabelList(WorkflowsEnforcementMixin, JobTemplateLabelList): parent_model = WorkflowJobTemplate new_in_310 = True -class WorkflowJobTemplateLaunch(RetrieveAPIView): +class WorkflowJobTemplateLaunch(WorkflowsEnforcementMixin, RetrieveAPIView): model = WorkflowJobTemplate @@ -3003,7 +2922,7 @@ class WorkflowJobTemplateLaunch(RetrieveAPIView): return Response(data, status=status.HTTP_201_CREATED) -class WorkflowJobRelaunch(GenericAPIView): +class WorkflowJobRelaunch(WorkflowsEnforcementMixin, GenericAPIView): model = WorkflowJob serializer_class = EmptySerializer @@ -3023,7 +2942,7 @@ class WorkflowJobRelaunch(GenericAPIView): # TODO: -class WorkflowJobTemplateWorkflowNodesList(SubListCreateAPIView): +class WorkflowJobTemplateWorkflowNodesList(WorkflowsEnforcementMixin, SubListCreateAPIView): model = WorkflowJobTemplateNode serializer_class = WorkflowJobTemplateNodeListSerializer @@ -3039,7 +2958,7 @@ class WorkflowJobTemplateWorkflowNodesList(SubListCreateAPIView): # TODO: -class WorkflowJobTemplateJobsList(SubListAPIView): +class WorkflowJobTemplateJobsList(WorkflowsEnforcementMixin, SubListAPIView): model = WorkflowJob serializer_class = WorkflowJobListSerializer @@ -3049,7 +2968,7 @@ class WorkflowJobTemplateJobsList(SubListAPIView): new_in_310 = True -class WorkflowJobTemplateSchedulesList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateSchedulesList(WorkflowsEnforcementMixin, SubListCreateAttachDetachAPIView): view_name = _("Workflow Job Template Schedules") @@ -3061,7 +2980,7 @@ class WorkflowJobTemplateSchedulesList(SubListCreateAttachDetachAPIView): new_in_310 = True -class WorkflowJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesAnyList(WorkflowsEnforcementMixin, SubListCreateAttachDetachAPIView): model = NotificationTemplate serializer_class = NotificationTemplateSerializer @@ -3070,7 +2989,7 @@ class WorkflowJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachA new_in_310 = True -class WorkflowJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesErrorList(WorkflowsEnforcementMixin, SubListCreateAttachDetachAPIView): model = NotificationTemplate serializer_class = NotificationTemplateSerializer @@ -3079,7 +2998,7 @@ class WorkflowJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetac new_in_310 = True -class WorkflowJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesSuccessList(WorkflowsEnforcementMixin, SubListCreateAttachDetachAPIView): model = NotificationTemplate serializer_class = NotificationTemplateSerializer @@ -3088,14 +3007,14 @@ class WorkflowJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDet new_in_310 = True -class WorkflowJobTemplateAccessList(ResourceAccessList): +class WorkflowJobTemplateAccessList(WorkflowsEnforcementMixin, ResourceAccessList): model = User # needs to be User for AccessLists's resource_model = WorkflowJobTemplate new_in_310 = True -class WorkflowJobTemplateObjectRolesList(SubListAPIView): +class WorkflowJobTemplateObjectRolesList(WorkflowsEnforcementMixin, SubListAPIView): model = Role serializer_class = RoleSerializer @@ -3108,7 +3027,7 @@ class WorkflowJobTemplateObjectRolesList(SubListAPIView): return Role.objects.filter(content_type=content_type, object_id=po.pk) -class WorkflowJobTemplateActivityStreamList(SubListAPIView): +class WorkflowJobTemplateActivityStreamList(WorkflowsEnforcementMixin, ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -3116,19 +3035,9 @@ class WorkflowJobTemplateActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_310 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(WorkflowJobTemplateActivityStreamList, self).get(request, *args, **kwargs) - # TODO: -class WorkflowJobList(ListCreateAPIView): +class WorkflowJobList(WorkflowsEnforcementMixin, ListCreateAPIView): model = WorkflowJob serializer_class = WorkflowJobListSerializer @@ -3136,14 +3045,14 @@ class WorkflowJobList(ListCreateAPIView): # TODO: -class WorkflowJobDetail(RetrieveDestroyAPIView): +class WorkflowJobDetail(WorkflowsEnforcementMixin, RetrieveDestroyAPIView): model = WorkflowJob serializer_class = WorkflowJobSerializer new_in_310 = True -class WorkflowJobWorkflowNodesList(SubListAPIView): +class WorkflowJobWorkflowNodesList(WorkflowsEnforcementMixin, SubListAPIView): model = WorkflowJobNode serializer_class = WorkflowJobNodeListSerializer @@ -3154,7 +3063,7 @@ class WorkflowJobWorkflowNodesList(SubListAPIView): new_in_310 = True -class WorkflowJobCancel(RetrieveAPIView): +class WorkflowJobCancel(WorkflowsEnforcementMixin, RetrieveAPIView): model = WorkflowJob serializer_class = WorkflowJobCancelSerializer @@ -3172,7 +3081,7 @@ class WorkflowJobCancel(RetrieveAPIView): return self.http_method_not_allowed(request, *args, **kwargs) -class WorkflowJobNotificationsList(SubListAPIView): +class WorkflowJobNotificationsList(WorkflowsEnforcementMixin, SubListAPIView): model = Notification serializer_class = NotificationSerializer @@ -3181,7 +3090,7 @@ class WorkflowJobNotificationsList(SubListAPIView): new_in_310 = True -class WorkflowJobActivityStreamList(SubListAPIView): +class WorkflowJobActivityStreamList(WorkflowsEnforcementMixin, ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -3189,16 +3098,6 @@ class WorkflowJobActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_310 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(WorkflowJobActivityStreamList, self).get(request, *args, **kwargs) - class SystemJobTemplateList(ListAPIView): @@ -3313,11 +3212,11 @@ class JobLabelList(SubListAPIView): parent_key = 'job' -class WorkflowJobLabelList(JobLabelList): +class WorkflowJobLabelList(WorkflowsEnforcementMixin, JobLabelList): parent_model = WorkflowJob -class JobActivityStreamList(SubListAPIView): +class JobActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -3325,16 +3224,6 @@ class JobActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(JobActivityStreamList, self).get(request, *args, **kwargs) - class JobStart(GenericAPIView): @@ -3909,7 +3798,7 @@ class AdHocCommandAdHocCommandEventsList(BaseAdHocCommandEventsList): new_in_220 = True -class AdHocCommandActivityStreamList(SubListAPIView): +class AdHocCommandActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer @@ -3917,16 +3806,6 @@ class AdHocCommandActivityStreamList(SubListAPIView): relationship = 'activitystream_set' new_in_220 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(AdHocCommandActivityStreamList, self).get(request, *args, **kwargs) - class AdHocCommandNotificationsList(SubListAPIView): @@ -4163,39 +4042,19 @@ class LabelDetail(RetrieveUpdateAPIView): new_in_300 = True -class ActivityStreamList(SimpleListAPIView): +class ActivityStreamList(ActivityStreamEnforcementMixin, SimpleListAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - # Okay, let it through. - return super(ActivityStreamList, self).get(request, *args, **kwargs) - - -class ActivityStreamDetail(RetrieveAPIView): +class ActivityStreamDetail(ActivityStreamEnforcementMixin, RetrieveAPIView): model = ActivityStream serializer_class = ActivityStreamSerializer new_in_145 = True - def get(self, request, *args, **kwargs): - # Sanity check: Does this license allow activity streams? - # If not, forbid this request. - if not feature_enabled('activity_streams'): - raise LicenseForbids(_('Your license does not allow use of ' - 'the activity stream.')) - - # Okay, let it through. - return super(ActivityStreamDetail, self).get(request, *args, **kwargs) - class RoleList(ListAPIView): From a231ef060880be27f5f9ac9d1285a2bbe3673d04 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Fri, 2 Dec 2016 17:00:08 -0500 Subject: [PATCH 2/2] Only enforce workflows once. --- awx/api/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index c656887dd9..954f783cdd 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2781,15 +2781,15 @@ class WorkflowJobTemplateNodeChildrenBaseList(WorkflowsEnforcementMixin, Enforce return None -class WorkflowJobTemplateNodeSuccessNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeSuccessNodesList(WorkflowJobTemplateNodeChildrenBaseList): relationship = 'success_nodes' -class WorkflowJobTemplateNodeFailureNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeFailureNodesList(WorkflowJobTemplateNodeChildrenBaseList): relationship = 'failure_nodes' -class WorkflowJobTemplateNodeAlwaysNodesList(WorkflowsEnforcementMixin, WorkflowJobTemplateNodeChildrenBaseList): +class WorkflowJobTemplateNodeAlwaysNodesList(WorkflowJobTemplateNodeChildrenBaseList): relationship = 'always_nodes' @@ -2811,15 +2811,15 @@ class WorkflowJobNodeChildrenBaseList(WorkflowsEnforcementMixin, SubListAPIView) return getattr(parent, self.relationship).all() -class WorkflowJobNodeSuccessNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeSuccessNodesList(WorkflowJobNodeChildrenBaseList): relationship = 'success_nodes' -class WorkflowJobNodeFailureNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeFailureNodesList(WorkflowJobNodeChildrenBaseList): relationship = 'failure_nodes' -class WorkflowJobNodeAlwaysNodesList(WorkflowsEnforcementMixin, WorkflowJobNodeChildrenBaseList): +class WorkflowJobNodeAlwaysNodesList(WorkflowJobNodeChildrenBaseList): relationship = 'always_nodes'