class ActivityLogDayCountViewset(viewsets.ModelViewSet): serializer_class = serializers.ActivityLogDayCountSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ["event_type__name", "actor_user", "effected_user"] permission_classes = [ core_permissions.ActionIs("list") & (core_permissions.IsCurrentUserInSpecificFilter("actor_user") | core_permissions.IsCurrentUserInSpecificFilter("effected_user") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "actor_user"), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "effected_user"), )) ] def get_queryset(self): query = models.LogEntry.objects.annotate( date=Cast("timestamp", output_field=DateField())) query = query.values("date").annotate(total=Count("date")) query = query.order_by("-date") filters = "&".join( [f"{key}={value}" for key, value in self.request.GET.items()]) query = query.annotate( filters=Value(filters, output_field=CharField())) return query
class WorkshopAttendanceViewset(viewsets.ModelViewSet): serializer_class = serializers.WorkshopAttendanceSerializer queryset = models.WorkshopAttendance.objects.order_by("pk") filter_backends = [DjangoFilterBackend] filterset_fields = ["attendee_user"] permission_classes = [ ActionIs("retrieve") & ( curriculum_permissions.IsWorkshopAttendee | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_workshop_attendance, ) ) | ActionIs("list") & ( core_permissions.IsCurrentUserInSpecificFilter("attendee_user") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "attendee_user" ), ) ) ]
def get_permissions(self): # breakpoint() # o = core_permissions.HasObjectPermission( # Team.PERMISSION_VIEW, # core_permissions.get_teams_from_user_filter("recruit_users"), # )() # o.has_permission(view=self, request=self.request) # wooo permission_classes = [IsReadOnly] if self.action == "retrieve": permission_classes = [ permissions.IsAdminUser | curriculum_permissions.IsProjectAssignee | curriculum_permissions.IsProjectReviewer | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_recruit_project, ) ] elif self.action == "list": permission_classes = [ permissions.IsAdminUser | core_permissions.IsCurrentUserInSpecificFilter("recruit_users") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "recruit_users" ), ) ] return [permission() for permission in permission_classes]
class CardSummaryViewset(viewsets.ModelViewSet): permission_classes = [ permissions.IsAdminUser | core_permissions.ActionIs("retrieve") & ( curriculum_permissions.IsCardAssignee | curriculum_permissions.IsCardReviewer | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_card ) ) | core_permissions.IsReadOnly | core_permissions.IsStaffUser | core_permissions.IsCurrentUserInSpecificFilter("assignees") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter("assignees"), ), ] serializer_class = serializers.CardSummarySerializer filter_backends = [DjangoFilterBackend, filters.OrderingFilter] filterset_fields = ["assignees", "content_item__content_type", "status"] ordering_fields = ["recruit_project__complete_time"] queryset = ( models.AgileCard.objects.order_by("order") .filter( Q(content_item__content_type=models.ContentItem.PROJECT) | Q(content_item__topic_needs_review=True) ) .prefetch_related("content_item") .prefetch_related("recruit_project") )
class RecruitProjectReviewViewset(viewsets.ModelViewSet): serializer_class = serializers.RecruitProjectReviewSerializer queryset = models.RecruitProjectReview.objects.order_by("-timestamp") filter_backends = [DjangoFilterBackend] filterset_fields = [ "status", "reviewer_user", "recruit_project", "recruit_project__recruit_users", ] permission_classes = [ ActionIs("list") & ( curriculum_permissions.IsCurrentUserInRecruitsForFilteredProject | curriculum_permissions.IsCurrentUserInReviewersForFilteredProject | core_permissions.IsCurrentUserInSpecificFilter("reviewer_user") | core_permissions.IsCurrentUserInSpecificFilter( "recruit_project__recruit_users" ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "recruit_project__recruit_users" ), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "reviewer_user" ), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_recruit_project_filter, ) ) | ActionIs("retrieve") & ( # curriculum_permissions.IsCurrentUserInRecruitsForFilteredProject # | curriculum_permissions.IsCurrentUserInReviewersForFilteredProject core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_recruit_project_review, ) ) ]
class TopicReviewViewset(viewsets.ModelViewSet): serializer_class = serializers.TopicReviewSerializer queryset = models.TopicReview.objects.order_by("pk") filter_backends = [DjangoFilterBackend] filterset_fields = [ "status", "reviewer_user", "topic_progress", "topic_progress__user", ] permission_classes = [ ActionIs("list") & ( curriculum_permissions.IsCurrentUserInUsersForFilteredTopicProgress | curriculum_permissions.IsCurrentUserInReviewersForFilteredTopicProgress | core_permissions.IsCurrentUserInSpecificFilter("reviewer_user") | core_permissions.IsCurrentUserInSpecificFilter("topic_progress__user") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "topic_progress__user" ), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "reviewer_user" ), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_topic_progress_filter, ) ) | ActionIs("retrieve") & ( curriculum_permissions.IsCurrentUserInUsersForFilteredTopicProgress | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_topic_review, ) ) ]
class ReviewTrustsViewSet(viewsets.ModelViewSet): permission_classes = [ permissions.IsAdminUser | ActionIs("list") & (core_permissions.IsCurrentUserInSpecificFilter("user") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter("user"), )) ] queryset = models.ReviewTrust.objects.order_by("user").all() serializer_class = serializers.ReviewTrustSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ["user"]
class BurnDownSnapShotViewset(viewsets.ModelViewSet): permission_classes = [ permissions.IsAdminUser | ActionIs("list") & (IsCurrentUserInSpecificFilter("user__id") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "user__id"), )) ] serializer_class = serializers.BurnDownSnapShotSerializer queryset = models.BurndownSnapshot.objects.order_by("-timestamp") filter_backends = [DjangoFilterBackend] filterset_fields = ["user__id", "timestamp"]
def get_permissions(self): permission_classes = [IsReadOnly] if self.action == "retrieve": permission_classes = [ curriculum_permissions.IsTopicProgressUser | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_topic_progress, ) ] elif self.action == "list": permission_classes = [ core_permissions.IsCurrentUserInSpecificFilter("user") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter("user"), ) ] return [permission() for permission in permission_classes]
class AgileCardViewset(viewsets.ModelViewSet): serializer_class = serializers.AgileCardSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ["assignees", "reviewers", "status"] queryset = ( models.AgileCard.objects.order_by("order") .prefetch_related("recruit_project") .prefetch_related("recruit_project__repository__pull_requests") ) permission_classes = [ ( core_permissions.ActionIs("retrieve") & ( curriculum_permissions.CardBelongsToRequestingUser | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=_get_teams_from_card, ) ) ) | ( core_permissions.ActionIs("list") & ( core_permissions.IsCurrentUserInSpecificFilter("assignees") | core_permissions.IsCurrentUserInSpecificFilter("reviewers") | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "assignees" ), ) | core_permissions.HasObjectPermission( permissions=Team.PERMISSION_VIEW, get_objects=core_permissions.get_teams_from_user_filter( "reviewers" ), ) ) ) ] def get_card_or_error(self, status_or_404, type_or_404): card = self.get_object() if status_or_404 and card.status != status_or_404: raise Http404() if card.content_type != type_or_404: raise Http404() return card @action( detail=True, methods=["post"], serializer_class=serializers.SetDueTimeSerializer, permission_classes=[ ( curriculum_permissions.IsCardAssignee & curriculum_permissions.CardDueTimeIsNotSet ) | IsStaffUser | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def set_card_due_time(self, request, pk=None): serializer = self.get_serializer(data=request.data) if serializer.is_valid(): card = self.get_object() card.set_due_time(serializer.data["due_time"]) return Response(serializers.AgileCardSerializer(card).data) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # @action( # detail=True, # methods=["post"], # serializer_class=serializers.AddReviewerUserSerializer, # permission_classes=[permissions.IsAdminUser | core_permissions.IsStaffUser], # ) # def add_reviewer(self, request, pk=None): # serializer = self.get_serializer(data=request.data) # if serializer.is_valid(): # TODO # return Response(serializers.AgileCardSerializer(card).data) # else: # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action( detail=True, methods=["post"], serializer_class=serializers.NewReviewSerializer, permission_classes=[ curriculum_permissions.IsCardReviewer | HasObjectPermission( permissions=Team.PERMISSION_REVIEW_CARDS, get_objects=_get_teams_from_card, ) | HasObjectPermission( permissions=Team.PERMISSION_TRUSTED_REVIEWER, get_objects=_get_teams_from_card, ) ], ) def add_review(self, request, pk=None): card = self.get_object() serializer = self.get_serializer(data=request.data) if serializer.is_valid(): if card.content_item.content_type == models.ContentItem.PROJECT: if card.recruit_project == None: raise Http404 review = models.RecruitProjectReview.objects.create( status=serializer.data["status"], timestamp=timezone.now(), comments=serializer.data["comments"], recruit_project=card.recruit_project, reviewer_user=request.user, ) log_creators.log_project_competence_review_done(review) elif card.content_item.content_type == models.ContentItem.TOPIC: if card.topic_progress == None: raise Http404 review = models.TopicReview.objects.create( status=serializer.data["status"], timestamp=timezone.now(), comments=serializer.data["comments"], topic_progress=card.topic_progress, reviewer_user=request.user, ) log_creators.log_topic_competence_review_done(review) card.refresh_from_db() return Response(serializers.AgileCardSerializer(card).data) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ curriculum_permissions.IsCardAssignee | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def request_review(self, request, pk=None): card: models.AgileCard = self.get_object() if card.recruit_project: card.recruit_project.request_review(force_timestamp=timezone.now()) elif card.topic_progress: card.finish_topic() else: raise Http404 card.refresh_from_db() assert ( card.status == models.AgileCard.IN_REVIEW ), f"Expected to be in review, but got {card.status}" return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ curriculum_permissions.IsCardAssignee | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def cancel_review_request(self, request, pk=None): card = self.get_object() if card.status != models.AgileCard.IN_REVIEW: raise Http404() if card.recruit_project: card.recruit_project.cancel_request_review() elif card.topic_progress: card.topic_progress.cancel_request_review() # card.status = models.AgileCard.IN_PROGRESS # card.save() return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ ( curriculum_permissions.IsCardAssignee & curriculum_permissions.CardCanStart ) | ( HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) & curriculum_permissions.CardCanForceStart ), ], ) def start_project(self, request, pk=None): card: models.AgileCard = self.get_card_or_error( status_or_404=None, type_or_404=models.ContentItem.PROJECT, ) card.start_project() log_creators.log_card_started(card=card, actor_user=request.user) return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.ProjectSubmitLink, permission_classes=[ curriculum_permissions.IsCardAssignee | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def set_project_link(self, request, pk=None): card = self.get_card_or_error( status_or_404=None, type_or_404=models.ContentItem.PROJECT, ) content_item = card.content_item assert ( content_item.project_submission_type == content_item.LINK ), "Cannot submit a link for project with submision type: {content_item.project_submission_type}\n\tcard={card}" serializer = self.get_serializer(data=request.data) if serializer.is_valid(): card.recruit_project.link_submission = serializer.data["link_submission"] card.recruit_project.save() card.refresh_from_db() return Response(serializers.AgileCardSerializer(card).data) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ ( curriculum_permissions.IsCardAssignee & curriculum_permissions.CardCanStart ) | ( HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) & curriculum_permissions.CardCanForceStart ), ], ) def start_topic(self, request, pk=None): card = self.get_card_or_error( status_or_404=models.AgileCard.READY, type_or_404=models.ContentItem.TOPIC ) if not card.can_start(): raise HttpResponseForbidden() card.start_topic() return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ curriculum_permissions.IsCardAssignee | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def stop_topic(self, request, pk=None): card = self.get_card_or_error( status_or_404=models.AgileCard.IN_PROGRESS, type_or_404=models.ContentItem.TOPIC, ) card.stop_topic() return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ curriculum_permissions.IsCardAssignee | HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def finish_topic(self, request, pk=None): card = self.get_card_or_error( status_or_404=models.AgileCard.IN_PROGRESS, type_or_404=models.ContentItem.TOPIC, ) card.finish_topic() return Response(serializers.AgileCardSerializer(card).data) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def mark_workshop_attendance(self, request, pk=None): card = self.get_card_or_error( status_or_404=None, type_or_404=models.ContentItem.WORKSHOP ) card.attended_workshop(timestamp=timezone.now()) return Response(serializers.AgileCardSerializer(card).data) # serializer = self.get_serializer(data=request.data) # if serializer.is_valid(): # card.attended_workshop(timestamp = serializer.data['timestamp']) # return Response(serializers.AgileCardSerializer(card).data) # else: # return Response(serializer.errors, # status=status.HTTP_400_BAD_REQUEST) @action( detail=True, methods=["post"], serializer_class=serializers.NoArgs, permission_classes=[ HasObjectPermission( permissions=Team.PERMISSION_MANAGE_CARDS, get_objects=_get_teams_from_card, ) ], ) def cancel_workshop_attendance(self, request, pk=None): card = self.get_card_or_error( status_or_404=models.AgileCard.COMPLETE, type_or_404=models.ContentItem.WORKSHOP, ) card.delete_workshop_attendance() return Response(serializers.AgileCardSerializer(card).data)