def update(self, request, pk): """Update Event. Needs BodyRole with `UpdE` for at least one associated body. Disassociating bodies from the event requires the `DelE` permission and associating needs `AddE`""" # Prevent events without any body if 'bodies_id' not in request.data or not request.data['bodies_id']: return forbidden_no_privileges() # Get difference in bodies event = self.get_event(pk) old_bodies_id = [str(x.id) for x in event.bodies.all()] new_bodies_id = request.data['bodies_id'] added_bodies = diff_set(new_bodies_id, old_bodies_id) removed_bodies = diff_set(old_bodies_id, new_bodies_id) # Check if user can add events for new bodies can_add_events = all([ user_has_privilege(request.user.profile, id, 'AddE') for id in added_bodies ]) # Check if user can remove events for removed can_del_events = all([ user_has_privilege(request.user.profile, id, 'DelE') for id in removed_bodies ]) # Check if the user can update event for any of the old bodies can_update = any([ user_has_privilege(request.user.profile, id, 'UpdE') for id in old_bodies_id ]) if can_add_events and can_del_events and can_update: # Create added unreusable venues, unlink deleted ones old_venue_names = [x.name for x in event.venues.all()] new_venue_names = request.data['venue_names'] added_venues = diff_set(new_venue_names, old_venue_names) common_venues = list( set(old_venue_names).intersection(new_venue_names)) common_venue_ids = [ str(x.id) for x in event.venues.filter(name__in=common_venues) ] added_venue_ids = create_unreusable_locations(added_venues) request.data['venue_ids'] = added_venue_ids + common_venue_ids return super().update(request, pk) return forbidden_no_privileges()
def update(self, request, pk): """Update Location. This requires the user to have the 'Location' institute permission or BodyRole for the event using the location if the it is not reusable.""" # Allow insti privelege to do anything if user_has_insti_privilege(request.user.profile, 'Location'): return super().update(request, pk) # Disallow modifying reusable locations or marking reusable location = Location.objects.get(id=pk) if 'reusable' in request.data: if (request.data['reusable'] != location.reusable) or location.reusable: return forbidden_no_privileges() # Check if user has update privileges for each associated event for event in location.events.all(): can_update = any([ user_has_privilege(request.user.profile, str(b.id), 'UpdE') for b in event.bodies.all() ]) if not can_update: return forbidden_no_privileges() return super().update(request, pk)
def update(self, request, pk): """Update Body. Needs the `UpdB` permission.""" if not user_has_privilege(request.user.profile, pk, 'UpdB'): return forbidden_no_privileges() return super().update(request, pk)
def update(self, request, pk): """Update/Verify an achievement. Needs BodyRole with `VerA` or can patch own achievement""" # Get the achievement currently in database achievement = get_object_or_404(self.queryset, id=pk) # Check if this is a patch request and the user is patching if request.method == 'PATCH' and request.user.profile == achievement.user: achievement.hidden = bool(request.data['hidden']) achievement.save(update_fields=['hidden']) return Response(status=204) # Check if the user has privileges for updating if not user_has_privilege(request.user.profile, achievement.body.id, "VerA"): return forbidden_no_privileges() # Prevent achievements without any body if 'body' not in request.data or not request.data[ 'body'] or request.data['body'] != str(achievement.body.id): return Response( { "message": "invalid body", "detail": "The body for this achievement is changed or invalid." }, status=400) return super().update(request, pk)
def retrieve(self, request, pk): """Get a achievement offer.""" # Get current object offer = get_object_or_404(self.queryset, id=pk) data = OfferedAchievementSerializer(offer).data # Extra fields in user serializer extra_fields = [] # Query for getting users query = offer.achievements.filter( verified=True).prefetch_related('user') # Check for verification privilege if user_has_privilege(request.user.profile, offer.body.id, "VerA"): data['secret'] = offer.secret # Add extra fields for privileged users extra_fields = [ 'roll_no', 'email', 'contact_no', 'department_name', 'degree' ] else: # Filter out hidden achievements query = query.filter(hidden=False) # Get users haveing this achievement users = [a.user for a in query] data['users'] = UserProfileSerializer(users, many=True, context={ 'extra': extra_fields }).data return Response(data)
def destroy(self, request, pk): if user_has_insti_privilege(request.user.profile, 'RoleB'): return super().destroy(request, pk) bodyid = str(BodyRole.objects.get(id=pk).body.id) if not user_has_privilege(request.user.profile, bodyid, 'Role'): return forbidden_no_privileges() return super().destroy(request, pk)
def create(self, request): """Offer a new achievement for an event.""" # Check for event add privilege if not user_has_privilege(request.user.profile, request.data['body'], "AddE"): return forbidden_no_privileges() return super().create(request)
def create(self, request): if user_has_insti_privilege(request.user.profile, 'RoleB'): return super().create(request) if not 'body' in request.data or not request.data['body']: return Response({"body": "body is required"}, status=400) if not user_has_privilege(request.user.profile, request.data['body'], 'Role'): return forbidden_no_privileges() return super().create(request)
def destroy(self, request, pk): """Delete Event. Needs `DelE` permission for all associated bodies.""" event = self.get_event(pk) if all([user_has_privilege(request.user.profile, str(body.id), 'DelE') for body in event.bodies.all()]): return super().destroy(request, pk) return forbidden_no_privileges()
def destroy(self, request, pk): """Update an offered achievement.""" # Get current object offer = get_object_or_404(self.queryset, id=pk) # Check for event add privilege if not user_has_privilege(request.user.profile, offer.body.id, "AddE"): return forbidden_no_privileges() return super().destroy(request, pk)
def can_update_bodies(new_bodies_id, event, profile): """Check if the user is permitted to change the event bodies to ones given.""" # Get current and difference in body ids old_bodies_id = [str(x.id) for x in event.bodies.all()] added_bodies = diff_set(new_bodies_id, old_bodies_id) removed_bodies = diff_set(old_bodies_id, new_bodies_id) # Check if user can add events for new bodies can_add_events = all( [user_has_privilege(profile, bid, 'AddE') for bid in added_bodies]) # Check if user can remove events for removed can_del_events = all( [user_has_privilege(profile, bid, 'DelE') for bid in removed_bodies]) # Check if the user can update event for any of the old bodies can_update = any( [user_has_privilege(profile, bid, 'UpdE') for bid in old_bodies_id]) return can_add_events and can_del_events and can_update
def destroy(self, request, pk): """Delete an achievement or request. Needs BodyRole with `VerA`""" # Get the achievement currently in database achievement = get_object_or_404(self.queryset, id=pk) # Check for permission if not user_has_privilege(request.user.profile, achievement.body.id, "VerA"): return forbidden_no_privileges() return super().destroy(request, pk)
def update(self, request, pk): if user_has_insti_privilege(request.user.profile, 'RoleB'): return super().update(request, pk) body = BodyRole.objects.get(id=pk).body if request.data['body'] != str(body.id): return Response({ 'message': 'body is immutable', 'detail': 'Body cannot be changed. Create a new role.' }, status=400) if not user_has_privilege(request.user.profile, str(body.id), 'Role'): return forbidden_no_privileges() return super().update(request, pk)
def create(self, request): """Create Event. Needs `AddE` permission for each body to be associated.""" if all([ user_has_privilege(request.user.profile, id, 'AddE') for id in request.data['bodies_id'] ]): # Fill in ids of venues request.data['venue_ids'] = create_unreusable_locations( request.data['venue_names']) return super().create(request) return forbidden_no_privileges()
def list_body(self, request, pk): """List the user's achivements and requests.""" if not user_has_privilege(request.user.profile, pk, "VerA"): return forbidden_no_privileges() self.queryset = AchievementUserSerializer.setup_eager_loading( self.queryset) self.queryset = self.queryset.filter(body__id=pk, dismissed=False) serializer = AchievementUserSerializer(self.queryset, many=True, context={'request': request}) return Response(serializer.data)
def destroy(self, request, pk): if user_has_insti_privilege(request.user.profile, 'RoleB'): return super().destroy(request, pk) # Check for permission body_role = BodyRole.objects.get(id=pk) bodyid = str(body_role.body.id) if not user_has_privilege(request.user.profile, bodyid, 'Role'): return forbidden_no_privileges() # Check for former users if body_role.former_users.count() > 0: return forbidden_no_privileges() return super().destroy(request, pk)