def create(self, request, *args, **kwargs): model_name = self.queryset.model._meta.model_name app_name = self.queryset.model._meta.app_label perm = '{}.add_{}'.format(app_name, model_name) with transaction.atomic(): response = super(PublicProjectViewSet, self).create(request, *args, **kwargs) user = request.user obj = self.queryset.model.objects.get(pk=response.data['id']) project = get_project_for_object(Project, obj) # Delete the object if the user doesn't have the right permissions # to create this. The object may get created without checking for # permissions, since the viewset returns True if the user just has # the required role in any organisation. If the newly created # object is not a project, and the user doesn't have permissions to # create it, we delete the object. if obj != project and not (user.has_perm( 'rsr.view_project', project) and user.has_perm(perm, obj)): obj.delete() if obj.pk is None: raise exceptions.PermissionDenied elif project is not None: log_project_changes(request.user, project, obj, {}, 'added') delete_project_from_project_directory_cache(project.pk) project.schedule_iati_checks() return response
def update(self, request, *args, **kwargs): response = super(PublicProjectViewSet, self).update(request, *args, **kwargs) obj = self.get_object() project = get_project_for_object(Project, obj) if project is not None: log_project_changes(request.user, project, obj, request.data, 'changed') delete_project_from_project_directory_cache(project.pk) project.schedule_iati_checks() return response
def destroy(self, request, *args, **kwargs): obj = self.get_object() project = get_project_for_object(Project, obj) try: response = super(PublicProjectViewSet, self).destroy(request, *args, **kwargs) except ProtectedError: msg = _("{}s with updates cannot be deleted".format( self.queryset.model.__name__)) return Response(msg, status=status.HTTP_405_METHOD_NOT_ALLOWED) if project is not None: log_project_changes(request.user, project, obj, {}, 'deleted') delete_project_from_project_directory_cache(project.pk) project.schedule_iati_checks() return response
def has_perm(self, user, perm, obj=None): if not user.is_authenticated: return False groups = groups_from_permission(perm) all_roles = ProjectRole.objects.filter(Q(user=user) & groups) if obj is None: # obj=None calls are made by the DRF when checking if permissions # should be given for a "view", and not a specific object. # Check if the user has a project role with specified groups that # have the required permission, irrespective of which project the # role exists for. return all_roles.exists() project = get_project_for_object(Project, obj) if project is None: return False if not project.use_project_roles: # If the project is not using project roles, let the default # ObjectPermissionBackend handle the permisisons! return False # RSR admins and org admins of the reporting organisation will have # access, irrespective of the roles! Django super users have access # irrespective of any permission rules. # NOTE: We are using can_edit_access method, since anyone with # permissions to edit access, essentially has access to everything. if user.can_edit_access(project): return True roles = all_roles.filter(project=project) if roles.exists(): return True else: raise PermissionDenied